#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"
/*!
* @brief 恐怖の仮面への特殊処理
- * @param player_ptr ã\83\97ã\83¬ã\83¼ヤーへの参照ポインタ
+ * @param player_ptr ã\83\97ã\83¬ã\82¤ヤーへの参照ポインタ
* @param o_ptr 対象のオブジェクト構造体への参照ポインタ
* @return 追加能力/耐性がもらえるならtrue、もらえないならfalse
* @details
* 純戦士系職業は追加能力/耐性がもらえる。
* それ以外では、反感、太古の怨念、呪いが付き追加能力/耐性はもらえない。
*/
-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 CLASS_WARRIOR:
- case CLASS_ARCHER:
- case CLASS_CAVALRY:
- case CLASS_BERSERKER:
+ case PlayerClassType::WARRIOR:
+ case PlayerClassType::ARCHER:
+ case PlayerClassType::CAVALRY:
+ case PlayerClassType::BERSERKER:
return true;
default:
- add_flag(o_ptr->art_flags, TR_AGGRAVATE);
- add_flag(o_ptr->art_flags, TR_TY_CURSE);
- o_ptr->curse_flags.set({ TRC::CURSED, TRC::HEAVY_CURSE });
- o_ptr->curse_flags.set(get_curse(player_ptr, 2, o_ptr));
+ o_ptr->art_flags.set(TR_AGGRAVATE);
+ o_ptr->art_flags.set(TR_TY_CURSE);
+ o_ptr->curse_flags.set({ CurseTraitType::CURSED, CurseTraitType::HEAVY_CURSE });
+ o_ptr->curse_flags.set(get_curse(2, o_ptr));
return false;
}
}
/*!
* @brief 戦乙女ミリムの危ない水着への特殊処理 (セクシーギャルのみpval追加)
- * @param player_ptr ã\83\97ã\83¬ã\83¼ヤーへの参照ポインタ
+ * @param player_ptr ã\83\97ã\83¬ã\82¤ヤーへの参照ポインタ
* @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->pseikaku != PERSONALITY_SEXY))
+ if (!o_ptr->is_specific_artifact(FixedArtifactId::MILIM) || (player_ptr->ppersonality != PERSONALITY_SEXY)) {
return;
+ }
o_ptr->pval = 3;
- add_flag(o_ptr->art_flags, TR_STR);
- add_flag(o_ptr->art_flags, TR_INT);
- add_flag(o_ptr->art_flags, TR_WIS);
- add_flag(o_ptr->art_flags, TR_DEX);
- add_flag(o_ptr->art_flags, TR_CON);
- add_flag(o_ptr->art_flags, TR_CHR);
+ o_ptr->art_flags.set(TR_STR);
+ o_ptr->art_flags.set(TR_INT);
+ o_ptr->art_flags.set(TR_WIS);
+ o_ptr->art_flags.set(TR_DEX);
+ o_ptr->art_flags.set(TR_CON);
+ o_ptr->art_flags.set(TR_CHR);
}
/*!
* @brief 特定の固定アーティファクトの条件付き追加能力/耐性を付加する
* @attention プレイヤーの各種ステータスに依存した処理がある。
* @todo 折を見て関数名を変更すること。
- * @param player_ptr ã\83\97ã\83¬ã\83¼ヤーへの参照ポインタ
+ * @param player_ptr ã\83\97ã\83¬ã\82¤ヤーへの参照ポインタ
* @param o_ptr 対象のオブジェクト構造体ポインタ
* @param a_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 != CLASS_SAMURAI) {
- add_flag(o_ptr->art_flags, TR_NO_MAGIC);
- o_ptr->curse_flags.set(TRC::HEAVY_CURSE);
+ 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(CurseTraitType::HEAVY_CURSE);
}
return;
- case ART_ROBINTON:
- if (player_ptr->pclass == CLASS_BARD)
- add_flag(o_ptr->art_flags, TR_DEC_MANA);
+ case FixedArtifactId::ROBINTON:
+ if (pc.equals(PlayerClassType::BARD)) {
+ o_ptr->art_flags.set(TR_DEC_MANA);
+ }
return;
- case ART_XIAOLONG:
- if (player_ptr->pclass == CLASS_MONK)
- add_flag(o_ptr->art_flags, TR_BLOWS);
+ 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)
- add_flag(o_ptr->art_flags, TR_AGGRAVATE);
+ 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:
* @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;
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;
+ }
}
}
* @param a_ptr 固定アーティファクト情報への参照ポインタ
* @param q_ptr オブジェクト情報への参照ポインタ
*/
-static void invest_curse_to_fixed_artifact(player_type *player_ptr, 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))
- o_ptr->curse_flags.set(get_curse(player_ptr, 0, o_ptr));
+ 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))
- o_ptr->curse_flags.set(get_curse(player_ptr, 1, o_ptr));
+ 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))
- o_ptr->curse_flags.set(get_curse(player_ptr, 2, o_ptr));
+ if (a_ref.gen_flags.has(ItemGenerationTraitType::RANDOM_CURSE2)) {
+ o_ptr->curse_flags.set(get_curse(2, o_ptr));
+ }
}
/*!
* @brief オブジェクトに指定した固定アーティファクトをオブジェクトに割り当てる。
- * @param player_ptr ã\83\97ã\83¬ã\83¼ヤーへの参照ポインタ
+ * @param player_ptr ã\83\97ã\83¬ã\82¤ヤーへの参照ポインタ
* @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->xtra2 = a_ptr->act_idx;
-
- invest_curse_to_fixed_artifact(player_ptr, 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);
}
/*!
* @brief フロアの指定された位置に固定アーティファクトを生成する。 / Create the artifact of the specified number
* @details 固定アーティファクト構造体から基本ステータスをコピーした後、所定の座標でdrop_item()で落とす。
- * @param player_ptr ã\83\97ã\83¬ã\83¼ヤーへの参照ポインタ
+ * @param player_ptr ã\83\97ã\83¬ã\82¤ヤーへの参照ポインタ
* @param a_idx 生成する固定アーティファクト構造体のID
* @param y アイテムを落とす地点のy座標
* @param x アイテムを落とす地点のx座標
* 仮に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(player_ptr, 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) ? true : false;
+ a_ref.is_generated = true;
+ return true;
}
/*!
* @brief 非INSTA_ART型の固定アーティファクトの生成を確率に応じて試行する。
* Mega-Hack -- Attempt to create one of the "Special Objects"
- * @param player_ptr ã\83\97ã\83¬ã\83¼ヤーへの参照ポインタ
+ * @param player_ptr ã\83\97ã\83¬ã\82¤ヤーへの参照ポインタ
* @param o_ptr 生成に割り当てたいオブジェクトの構造体参照ポインタ
* @return 生成に成功したらTRUEを返す。
* @details
* 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 (ARTIFACT_IDX i = 0; i < max_a_idx; i++) {
- auto a_ptr = &a_info[i];
-
- if (a_ptr->name.empty())
- continue;
-
- if (a_ptr->cur_num)
+ for (const auto &[a_idx, a_ref] : artifacts_info) {
+ if (a_ref.name.empty()) {
continue;
+ }
- if (a_ptr->gen_flags.has(TRG::QUESTITEM))
+ if (a_ref.is_generated) {
continue;
+ }
- if (a_ptr->gen_flags.has(TRG::INSTA_ART))
+ if (a_ref.gen_flags.has(ItemGenerationTraitType::QUESTITEM)) {
continue;
+ }
- if (a_ptr->tval != o_ptr->tval)
+ if (a_ref.gen_flags.has(ItemGenerationTraitType::INSTA_ART)) {
continue;
+ }
- if (a_ptr->sval != o_ptr->sval)
+ if (a_ref.bi_key != o_ptr->bi_key) {
continue;
+ }
- if (a_ptr->level > floor_ptr->dun_level) {
- int d = (a_ptr->level - floor_ptr->dun_level) * 2;
- if (!one_in_(d))
+ if (a_ref.level > floor_ptr->dun_level) {
+ int d = (a_ref.level - floor_ptr->dun_level) * 2;
+ if (!one_in_(d)) {
continue;
+ }
}
- if (!one_in_(a_ptr->rarity))
+ if (!one_in_(a_ref.rarity)) {
continue;
+ }
- o_ptr->name1 = i;
+ o_ptr->fixed_artifact_idx = a_idx;
return true;
}
/*!
* @brief INSTA_ART型の固定アーティファクトの生成を確率に応じて試行する。
* Mega-Hack -- Attempt to create one of the "Special Objects"
- * @param player_ptr ã\83\97ã\83¬ã\83¼ヤーへの参照ポインタ
+ * @param player_ptr ã\83\97ã\83¬ã\82¤ヤーへの参照ポインタ
* @param o_ptr 生成に割り当てたいオブジェクトの構造体参照ポインタ
* @return 生成に成功したらTRUEを返す。
* @details
*\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 (ARTIFACT_IDX i = 0; i < max_a_idx; i++) {
- auto a_ptr = &a_info[i];
-
+ for (const auto &[a_idx, a_ref] : artifacts_info) {
/*! @note アーティファクト名が空の不正なデータは除外する / Skip "empty" artifacts */
- if (a_ptr->name.empty())
+ if (a_ref.name.empty()) {
continue;
+ }
/*! @note 既に生成回数がカウントされたアーティファクト、QUESTITEMと非INSTA_ARTは除外 / Cannot make an artifact twice */
- if (a_ptr->cur_num)
+ if (a_ref.is_generated) {
continue;
- if (a_ptr->gen_flags.has(TRG::QUESTITEM))
+ }
+ if (a_ref.gen_flags.has(ItemGenerationTraitType::QUESTITEM)) {
continue;
- if (!(a_ptr->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) */
- if (a_ptr->level > floor_ptr->object_level) {
+ /*! @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_ptr->level - floor_ptr->object_level) * 2;
- if (!one_in_(d))
+ int d = (a_ref.level - floor_ptr->object_level) * 2;
+ if (!one_in_(d)) {
continue;
+ }
}
/*! @note 1/(レア度)の確率を満たさないと除外される / Artifact "rarity roll" */
- if (!one_in_(a_ptr->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_ptr->tval, a_ptr->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(player_ptr, k_idx);
+ o_ptr->prep(bi_id);
- o_ptr->name1 = i;
+ o_ptr->fixed_artifact_idx = a_idx;
return true;
}