OSDN Git Service

Merge pull request #2948 from backwardsEric/sprintf-refactor-item_activation_aux
[hengbandforosx/hengbandosx.git] / src / artifact / fixed-art-generator.cpp
index a7c7d54..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"
 
@@ -40,9 +40,9 @@
  * 純戦士系職業は追加能力/耐性がもらえる。
  * それ以外では、反感、太古の怨念、呪いが付き追加能力/耐性はもらえない。
  */
-static bool invest_terror_mask(PlayerType *player_ptr, ObjectType *o_ptr)
+static bool invest_terror_mask(PlayerType *player_ptr, ItemEntity *o_ptr)
 {
-    if (o_ptr->fixed_artifact_idx != ART_TERROR) {
+    if (!o_ptr->is_specific_artifact(FixedArtifactId::TERROR)) {
         return false;
     }
 
@@ -66,9 +66,9 @@ static bool invest_terror_mask(PlayerType *player_ptr, ObjectType *o_ptr)
  * @param player_ptr プレイヤーへの参照ポインタ
  * @param o_ptr 対象のオブジェクト構造体への参照ポインタ
  */
-static void milim_swimsuit(PlayerType *player_ptr, ObjectType *o_ptr)
+static void milim_swimsuit(PlayerType *player_ptr, ItemEntity *o_ptr)
 {
-    if ((o_ptr->fixed_artifact_idx != ART_MILIM) || (player_ptr->ppersonality != PERSONALITY_SEXY)) {
+    if (!o_ptr->is_specific_artifact(FixedArtifactId::MILIM) || (player_ptr->ppersonality != PERSONALITY_SEXY)) {
         return;
     }
 
@@ -91,35 +91,35 @@ static void milim_swimsuit(PlayerType *player_ptr, ObjectType *o_ptr)
  * @details
  * 対象は村正、ロビントンのハープ、龍争虎鬪、ブラッディムーン、羽衣、天女の羽衣、ミリム
  */
-static void invest_special_artifact_abilities(PlayerType *player_ptr, ObjectType *o_ptr)
+static void invest_special_artifact_abilities(PlayerType *player_ptr, ItemEntity *o_ptr)
 {
     const auto pc = PlayerClass(player_ptr);
     switch (o_ptr->fixed_artifact_idx) {
-    case ART_MURAMASA:
+    case FixedArtifactId::MURAMASA:
         if (!pc.equals(PlayerClassType::SAMURAI)) {
             o_ptr->art_flags.set(TR_NO_MAGIC);
             o_ptr->curse_flags.set(CurseTraitType::HEAVY_CURSE);
         }
         return;
-    case ART_ROBINTON:
+    case FixedArtifactId::ROBINTON:
         if (pc.equals(PlayerClassType::BARD)) {
             o_ptr->art_flags.set(TR_DEC_MANA);
         }
         return;
-    case ART_XIAOLONG:
+    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:
+    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:
@@ -133,7 +133,7 @@ static void invest_special_artifact_abilities(PlayerType *player_ptr, ObjectType
  * @param a_ptr 固定アーティファクト情報への参照ポインタ
  * @param q_ptr オブジェクト情報への参照ポインタ
  */
-static void fixed_artifact_random_abilities(PlayerType *player_ptr, artifact_type *a_ptr, ObjectType *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;
@@ -145,15 +145,15 @@ static void fixed_artifact_random_abilities(PlayerType *player_ptr, artifact_typ
 
     invest_special_artifact_abilities(player_ptr, o_ptr);
 
-    if (a_ptr->gen_flags.has(ItemGenerationTraitType::XTRA_POWER)) {
+    if (a_ref.gen_flags.has(ItemGenerationTraitType::XTRA_POWER)) {
         give_power = true;
     }
 
-    if (a_ptr->gen_flags.has(ItemGenerationTraitType::XTRA_H_RES)) {
+    if (a_ref.gen_flags.has(ItemGenerationTraitType::XTRA_H_RES)) {
         give_resistance = true;
     }
 
-    if (a_ptr->gen_flags.has(ItemGenerationTraitType::XTRA_RES_OR_POWER)) {
+    if (a_ref.gen_flags.has(ItemGenerationTraitType::XTRA_RES_OR_POWER)) {
         if (one_in_(2)) {
             give_resistance = true;
         } else {
@@ -169,7 +169,7 @@ static void fixed_artifact_random_abilities(PlayerType *player_ptr, artifact_typ
         one_high_resistance(o_ptr);
     }
 
-    if (a_ptr->gen_flags.has(ItemGenerationTraitType::XTRA_DICE)) {
+    if (a_ref.gen_flags.has(ItemGenerationTraitType::XTRA_DICE)) {
         do {
             o_ptr->dd++;
         } while (one_in_(o_ptr->dd));
@@ -186,33 +186,33 @@ static void fixed_artifact_random_abilities(PlayerType *player_ptr, artifact_typ
  * @param a_ptr 固定アーティファクト情報への参照ポインタ
  * @param q_ptr オブジェクト情報への参照ポインタ
  */
-static void invest_curse_to_fixed_artifact(artifact_type *a_ptr, ObjectType *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(ItemGenerationTraitType::CURSED)) {
+    if (a_ref.gen_flags.has(ItemGenerationTraitType::CURSED)) {
         o_ptr->curse_flags.set(CurseTraitType::CURSED);
     }
 
-    if (a_ptr->gen_flags.has(ItemGenerationTraitType::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(ItemGenerationTraitType::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(ItemGenerationTraitType::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(ItemGenerationTraitType::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(ItemGenerationTraitType::RANDOM_CURSE2)) {
+    if (a_ref.gen_flags.has(ItemGenerationTraitType::RANDOM_CURSE2)) {
         o_ptr->curse_flags.set(get_curse(2, o_ptr));
     }
 }
@@ -223,23 +223,21 @@ static void invest_curse_to_fixed_artifact(artifact_type *a_ptr, ObjectType *o_p
  * @param o_ptr 生成に割り当てたいオブジェクトの構造体参照ポインタ
  * @return 適用したアーティファクト情報への参照ポインタ
  */
-artifact_type *apply_artifact(PlayerType *player_ptr, ObjectType *o_ptr)
+void apply_artifact(PlayerType *player_ptr, ItemEntity *o_ptr)
 {
-    auto a_ptr = &a_info[o_ptr->fixed_artifact_idx];
-    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);
 }
 
 /*!
@@ -254,26 +252,29 @@ artifact_type *apply_artifact(PlayerType *player_ptr, ObjectType *o_ptr)
  * 仮に2個以上存在可能かつ装備品以外の固定アーティファクトが作成されれば
  * drop_near()関数の返り値は信用できなくなる.
  */
-bool create_named_art(PlayerType *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;
     }
 
-    ObjectType forge;
+    ItemEntity forge;
     auto q_ptr = &forge;
-    q_ptr->prep(i);
+    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;
+    }
 
-    (void)apply_artifact(player_ptr, q_ptr);
-
-    return drop_near(player_ptr, q_ptr, -1, y, x) > 0;
+    a_ref.is_generated = true;
+    return true;
 }
 
 /*!
@@ -287,7 +288,7 @@ bool create_named_art(PlayerType *player_ptr, ARTIFACT_IDX a_idx, POSITION y, PO
  * This routine should only be called by "apply_magic()"\n
  * Note -- see "make_artifact_special()" and "apply_magic()"\n
  */
-bool make_artifact(PlayerType *player_ptr, ObjectType *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) {
@@ -298,7 +299,7 @@ bool make_artifact(PlayerType *player_ptr, ObjectType *o_ptr)
         return false;
     }
 
-    for (const auto &a_ref : a_info) {
+    for (const auto &[a_idx, a_ref] : artifacts_info) {
         if (a_ref.name.empty()) {
             continue;
         }
@@ -315,11 +316,7 @@ bool make_artifact(PlayerType *player_ptr, ObjectType *o_ptr)
             continue;
         }
 
-        if (a_ref.tval != o_ptr->tval) {
-            continue;
-        }
-
-        if (a_ref.sval != o_ptr->sval) {
+        if (a_ref.bi_key != o_ptr->bi_key) {
             continue;
         }
 
@@ -334,7 +331,7 @@ bool make_artifact(PlayerType *player_ptr, ObjectType *o_ptr)
             continue;
         }
 
-        o_ptr->fixed_artifact_idx = a_ref.idx;
+        o_ptr->fixed_artifact_idx = a_idx;
         return true;
     }
 
@@ -353,23 +350,21 @@ bool make_artifact(PlayerType *player_ptr, ObjectType *o_ptr)
  *\n
  * Note -- see "make_artifact()" and "apply_magic()"\n
  */
-bool make_artifact_special(PlayerType *player_ptr, ObjectType *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) {
         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()) {
             continue;
@@ -386,8 +381,7 @@ bool make_artifact_special(PlayerType *player_ptr, ObjectType *o_ptr)
             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;
@@ -401,12 +395,13 @@ bool make_artifact_special(PlayerType *player_ptr, ObjectType *o_ptr)
             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;
+        /*!
+         * @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;
             }
@@ -414,9 +409,9 @@ bool make_artifact_special(PlayerType *player_ptr, ObjectType *o_ptr)
 
         /*! @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->fixed_artifact_idx = a_ref.idx;
+        o_ptr->fixed_artifact_idx = a_idx;
         return true;
     }