OSDN Git Service

[Refactor] #3756 ItemEntity::is() とBaseitemKey::is() を定義した
[hengbandforosx/hengbandosx.git] / src / system / item-entity.cpp
index 94092bd..7ddc744 100644 (file)
@@ -10,6 +10,8 @@
 #include "artifact/fixed-art-types.h"
 #include "artifact/random-art-effects.h"
 #include "monster-race/monster-race.h"
+#include "object-enchant/activation-info-table.h"
+#include "object-enchant/dragon-breaths-table.h"
 #include "object-enchant/item-feeling.h"
 #include "object-enchant/object-curse.h"
 #include "object-enchant/special-object-flags.h"
@@ -18,6 +20,7 @@
 #include "smith/object-smith.h"
 #include "sv-definition/sv-lite-types.h"
 #include "sv-definition/sv-other-types.h"
+#include "sv-definition/sv-ring-types.h"
 #include "sv-definition/sv-weapon-types.h"
 #include "system/artifact-type-definition.h"
 #include "system/baseitem-info.h"
@@ -26,6 +29,7 @@
 #include "util/bit-flags-calculator.h"
 #include "util/enum-converter.h"
 #include "util/string-processor.h"
+#include <sstream>
 
 ItemEntity::ItemEntity()
     : bi_key(BaseitemKey(ItemKindType::NONE))
@@ -35,7 +39,6 @@ ItemEntity::ItemEntity()
 
 /*!
  * @brief アイテムを初期化する
- * Wipe an object clean.
  */
 void ItemEntity::wipe()
 {
@@ -44,8 +47,7 @@ void ItemEntity::wipe()
 
 /*!
  * @brief アイテムを複製する
- * Wipe an object clean.
- * @param j_ptr 複製元のオブジェクトの構造体参照ポインタ
+ * @param j_ptr 複製元アイテムへの参照ポインタ
  */
 void ItemEntity::copy_from(const ItemEntity *j_ptr)
 {
@@ -54,7 +56,6 @@ void ItemEntity::copy_from(const ItemEntity *j_ptr)
 
 /*!
  * @brief アイテム構造体にベースアイテムを作成する
- * @param player_ptr プレイヤーへの参照ポインタ
  * @param bi_id 新たに作成したいベースアイテム情報のID
  */
 void ItemEntity::prep(short new_bi_id)
@@ -108,9 +109,14 @@ void ItemEntity::prep(short new_bi_id)
     }
 }
 
+bool ItemEntity::is(ItemKindType tval) const
+{
+    return this->bi_key.is(tval);
+}
+
 /*!
- * @brief アイテムが武器として装備できるかどうかを返す / Check if an object is weapon (including bows)
- * @return æ­¦å\99¨ã\81¨ã\81\97ã\81¦ä½¿ã\81\88ã\82\8bã\81ªã\82\89ã\81°trueã\82\92è¿\94ã\81\99
+ * @brief 武器か否かを判定する
+ * @return æ­¦å\99¨ã\81\8bå\90¦ã\81\8b
  */
 bool ItemEntity::is_weapon() const
 {
@@ -118,8 +124,8 @@ bool ItemEntity::is_weapon() const
 }
 
 /*!
- * @brief アイテムが武器や矢弾として使用できるかを返す
- * @return æ­¦å\99¨ã\82\84ç\9f¢å¼¾ã\81¨ã\81\97ã\81¦ä½¿ã\81\88ã\82\8bã\81ªã\82\89ã\81°trueã\82\92è¿\94ã\81\99
+ * @brief 武器や矢弾として使用できるかを判定する
+ * @return æ­¦å\99¨ã\82\84ç\9f¢å¼¾ã\81¨ã\81\97ã\81¦ä½¿ã\81\88ã\82\8bã\81\8bå\90¦ã\81\8b
  */
 bool ItemEntity::is_weapon_ammo() const
 {
@@ -127,8 +133,8 @@ bool ItemEntity::is_weapon_ammo() const
 }
 
 /*!
- * @brief アイテムが武器、防具、矢弾として使用できるかを返す / Check if an object is weapon, armour or ammo
- * @return æ­¦å\99¨ã\80\81é\98²å\85·ã\80\81ç\9f¢å¼¾ã\81¨ã\81\97ã\81¦ä½¿ã\81\88ã\82\8bã\81ªã\82\89ã\81°trueã\82\92è¿\94ã\81\99
+ * @brief 武器、防具、矢弾として使用できるかを判定する
+ * @return æ­¦å\99¨ã\80\81é\98²å\85·ã\80\81ç\9f¢å¼¾ã\81¨ã\81\97ã\81¦ä½¿ã\81\88ã\82\8bã\81\8bå\90¦ã\81\8b
  */
 bool ItemEntity::is_weapon_armour_ammo() const
 {
@@ -136,8 +142,8 @@ bool ItemEntity::is_weapon_armour_ammo() const
 }
 
 /*!
- * @brief アイテムが近接武器として装備できるかを返す / Melee weapons
- * @return è¿\91æ\8e¥æ­¦å\99¨ã\81¨ã\81\97ã\81¦ä½¿ã\81\88ã\82\8bã\81ªã\82\89ã\81°trueã\82\92è¿\94ã\81\99
+ * @brief 近接武器として装備できるかを判定する
+ * @return è¿\91æ\8e¥æ­¦å\99¨ã\81¨ã\81\97ã\81¦ä½¿ã\81\88ã\82\8bã\81\8bå\90¦ã\81\8b
  */
 bool ItemEntity::is_melee_weapon() const
 {
@@ -145,8 +151,8 @@ bool ItemEntity::is_melee_weapon() const
 }
 
 /*!
- * @brief エッセンスの付加可能な武器や矢弾かを返す
- * @return ã\82¨ã\83\83ã\82»ã\83³ã\82¹ã\81®ä»\98å\8a å\8f¯è\83½ã\81ªæ­¦å\99¨ã\81\8bç\9f¢å¼¾ã\81ªã\82\89ã\81°trueã\82\92è¿\94ã\81\99ã\80\82
+ * @brief エッセンスの付加可能な武器や矢弾かを判定する
+ * @return ã\82¨ã\83\83ã\82»ã\83³ã\82¹ã\81®ä»\98å\8a å\8f¯è\83½ã\81ªæ­¦å\99¨ã\81\8bç\9f¢å¼¾ã\81\8bå\90¦ã\81\8b
  */
 bool ItemEntity::is_melee_ammo() const
 {
@@ -154,8 +160,8 @@ bool ItemEntity::is_melee_ammo() const
 }
 
 /*!
- * @brief アイテムが装備可能であるかを返す / Wearable including all weapon, all armour, bow, light source, amulet, and ring
- * @return è£\85å\82\99å\8f¯è\83½ã\81ªã\82\89ã\81°TRUEã\82\92è¿\94ã\81\99
+ * @brief 装備可能であるかを判定する
+ * @return è£\85å\82\99å\8f¯è\83½ã\81\8bå\90¦ã\81\8b
  */
 bool ItemEntity::is_wearable() const
 {
@@ -163,8 +169,8 @@ bool ItemEntity::is_wearable() const
 }
 
 /*!
- * @brief アイテムが装備品であるかを返す(ItemEntity::is_wearableに矢弾を含む) / Equipment including all wearable objects and ammo
- * @return è£\85å\82\99å\93\81ã\81ªã\82\89ã\81°trueã\82\92è¿\94ã\81\99
+ * @brief 装備品であるかを判定する
+ * @return è£\85å\82\99å\93\81ã\81\8bå\90¦ã\81\8b
  */
 bool ItemEntity::is_equipment() const
 {
@@ -172,8 +178,8 @@ bool ItemEntity::is_equipment() const
 }
 
 /*!
- * @brief 武器匠の「武器」鑑定対象になるかを判定する。/ Hook to specify "weapon"
- * @return 対象になるならtrueを返す。
+ * @brief 武器匠の「武器」鑑定対象になるかを判定する
+ * @return 鑑定対象か否か
  */
 bool ItemEntity::is_orthodox_melee_weapons() const
 {
@@ -181,8 +187,8 @@ bool ItemEntity::is_orthodox_melee_weapons() const
 }
 
 /*!
- * @brief 修復対象となる壊れた武器かを判定する。 / Hook to specify "broken weapon"
- * @return ä¿®å¾©å¯¾è±¡ã\81«ã\81ªã\82\8bã\81ªã\82\89TRUEã\82\92è¿\94ã\81\99ã\80\82
+ * @brief 修復対象となる壊れた武器かを判定する
+ * @return ä¿®å¾©å¯¾è±¡ã\81\8bå\90¦ã\81\8b
  */
 bool ItemEntity::is_broken_weapon() const
 {
@@ -190,8 +196,8 @@ bool ItemEntity::is_broken_weapon() const
 }
 
 /*!
- * @brief アイテムが投射可能な武器かどうかを返す。
- * @return æ\8a\95å°\84å\8f¯è\83½ã\81ªæ­¦å\99¨ã\81ªã\82\89ã\81°true
+ * @brief 投射可能な武器かどうかを判定する
+ * @return æ\8a\95å°\84å\8f¯è\83½ã\81\8bå\90¦ã\81\8b
  */
 bool ItemEntity::is_throwable() const
 {
@@ -199,8 +205,8 @@ bool ItemEntity::is_throwable() const
 }
 
 /*!
- * @brief ã\82¢ã\82¤ã\83\86ã\83 ã\81\8cã\81©ã\81¡ã\82\89ã\81®æ\89\8bã\81«ã\82\82è£\85å\82\99ã\81§ã\81\8dã\82\8bæ­¦å\99¨ã\81\8bã\81©ã\81\86ã\81\8bã\81®å\88¤å®\9a
- * @return 左右両方の手で装備できるならばtrueを返す。
+ * @brief ã\81©ã\81¡ã\82\89ã\81®æ\89\8bã\81«ã\82\82è£\85å\82\99ã\81§ã\81\8dã\82\8bæ­¦å\99¨ã\81\8bã\82\92å\88¤å®\9aã\81\99ã\82\8b
+ * @return 左右両方の手で装備可能か否か
  */
 bool ItemEntity::is_wieldable_in_etheir_hand() const
 {
@@ -208,18 +214,17 @@ bool ItemEntity::is_wieldable_in_etheir_hand() const
 }
 
 /*!
- * @brief アイテムが強化不能武器であるかを返す / Poison needle can not be enchanted
- * @return å¼·å\8c\96ä¸\8dè\83½ã\81ªã\82\89ã\81°trueã\82\92è¿\94ã\81\99
+ * @brief 強化不能武器であるかを判定する
+ * @return å¼·å\8c\96ä¸\8dè\83½ã\81\8bå\90¦ã\81\8b
  */
 bool ItemEntity::refuse_enchant_weapon() const
 {
-    return this->bi_key == BaseitemKey(ItemKindType::SWORD, SV_POISON_NEEDLE);
+    return this->bi_key.refuse_enchant_weapon();
 }
 
 /*!
- * @brief アイテムが強化可能武器であるかを返す /
- * Check if an object is weapon (including bows and ammo) and allows enchantment
- * @return 強化可能ならばtrueを返す
+ * @brief 強化可能武器であるかを判定する
+ * @return 強化可能か否か
  */
 bool ItemEntity::allow_enchant_weapon() const
 {
@@ -227,9 +232,8 @@ bool ItemEntity::allow_enchant_weapon() const
 }
 
 /*!
- * @brief アイテムが強化可能な近接武器であるかを返す /
- * Check if an object is melee weapon and allows enchantment
- * @return 強化可能な近接武器ならばtrueを返す
+ * @brief 強化可能な近接武器であるかを判定する
+ * @return 強化可能な近接武器か否か
  */
 bool ItemEntity::allow_enchant_melee_weapon() const
 {
@@ -237,18 +241,17 @@ bool ItemEntity::allow_enchant_melee_weapon() const
 }
 
 /*!
- * @brief アイテムが両手持ち可能な武器かを返す /
- * Check if an object is melee weapon and allows wielding with two-hands
- * @return 両手持ち可能ならばTRUEを返す
+ * @brief 両手持ち可能な武器かを判定する
+ * @return 両手持ち可能か否か
  */
 bool ItemEntity::allow_two_hands_wielding() const
 {
-    return this->is_melee_weapon() && ((this->weight > 99) || (this->bi_key.tval() == ItemKindType::POLEARM));
+    return this->is_melee_weapon() && ((this->weight > 99) || this->is(ItemKindType::POLEARM));
 }
 
 /*!
- * @brief アイテムが矢弾として使用できるかどうかを返す / Check if an object is ammo
- * @return ç\9f¢å¼¾ã\81¨ã\81\97ã\81¦ä½¿ã\81\88ã\82\8bã\81ªã\82\89ã\81°trueã\82\92è¿\94ã\81\99
+ * @brief 矢弾として使用できるかどうかを判定する
+ * @return ç\9f¢å¼¾ã\81¨ã\81\97ã\81¦ä½¿ã\81\88ã\82\8bã\81\8bå\90¦ã\81\8b
  */
 bool ItemEntity::is_ammo() const
 {
@@ -256,14 +259,12 @@ bool ItemEntity::is_ammo() const
 }
 
 /*!
- * @brief 対象のアイテムが矢やクロスボウの矢の材料になるかを返す。/
- * Hook to determine if an object is contertible in an arrow/bolt
- * @return 材料にできるならtrueを返す
+ * @brief 対象の矢やクロスボウの矢の材料になるかを判定する
+ * @return 材料にできるか否か
  */
 bool ItemEntity::is_convertible() const
 {
-    const auto tval = this->bi_key.tval();
-    auto is_convertible = (tval == ItemKindType::JUNK) || (tval == ItemKindType::SKELETON);
+    auto is_convertible = this->is(ItemKindType::JUNK) || this->is(ItemKindType::SKELETON);
     is_convertible |= this->bi_key == BaseitemKey(ItemKindType::CORPSE, SV_SKELETON);
     return is_convertible;
 }
@@ -276,8 +277,8 @@ bool ItemEntity::is_lance() const
 }
 
 /*!
- * @brief アイテムが防具として装備できるかどうかを返す
- * @return é\98²å\85·ã\81¨ã\81\97ã\81¦è£\85å\82\99ã\81§ã\81\8dã\82\8bã\81ªã\82\89ã\81°trueã\82\92è¿\94ã\81\99
+ * @brief 防具かを判定する
+ * @return é\98²å\85·ã\81\8bå\90¦ã\81\8b
  */
 bool ItemEntity::is_protector() const
 {
@@ -285,8 +286,8 @@ bool ItemEntity::is_protector() const
 }
 
 /*!
- * @brief ã\82¢ã\82¤ã\83\86ã\83 ã\81\8cã\82ªã\83¼ã\83©ã\82\92çº\8fã\81\88ã\82\8bé\98²å\85·ã\81\8bã\81©ã\81\86ã\81\8bã\82\92è¿\94ã\81\99
- * @return ã\82ªã\83¼ã\83©ã\82\92çº\8fã\81\88ã\82\8bã\81ªã\82\89ã\81°trueã\82\92è¿\94ã\81\99
+ * @brief ã\82ªã\83¼ã\83©ã\82\92çº\8fã\81\88ã\82\8bé\98²å\85·ã\81\8bã\81©ã\81\86ã\81\8bã\82\92å\88¤å®\9aã\81\99ã\82\8b
+ * @return ã\82ªã\83¼ã\83©ã\82\92çº\8fã\81\88ã\82\8bã\81\8bå\90¦ã\81\8b
  */
 bool ItemEntity::can_be_aura_protector() const
 {
@@ -294,9 +295,8 @@ bool ItemEntity::can_be_aura_protector() const
 }
 
 /*!
- * @brief アイテムがレアアイテムかどうかを返す /
- * Rare weapons/aromors including Blade of Chaos, Dragon armors, etc.
- * @return レアアイテムならばTRUEを返す
+ * @brief レアアイテムかどうかを判定する
+ * @return レアアイテムか否か
  */
 bool ItemEntity::is_rare() const
 {
@@ -304,8 +304,8 @@ bool ItemEntity::is_rare() const
 }
 
 /*!
- * @brief ã\82¢ã\82¤ã\83\86ã\83 ã\81\8cã\82¨ã\82´ã\82¢ã\82¤ã\83\86ã\83 ã\81\8bã\81©ã\81\86ã\81\8bã\82\92è¿\94ã\81\99
- * @return ã\82¨ã\82´ã\82¢ã\82¤ã\83\86ã\83 ã\81ªã\82\89ã\81°trueã\82\92è¿\94ã\81\99
+ * @brief ã\82¨ã\82´ã\82¢ã\82¤ã\83\86ã\83 ã\81\8bã\81©ã\81\86ã\81\8bã\82\92å\88¤å®\9aã\81\99ã\82\8b
+ * @return ã\82¨ã\82´ã\82¢ã\82¤ã\83\86ã\83 ã\81\8bå\90¦ã\81\8b
  */
 bool ItemEntity::is_ego() const
 {
@@ -313,9 +313,8 @@ bool ItemEntity::is_ego() const
 }
 
 /*!
- * @brief アイテムが鍛冶師のエッセンス付加済みかを返す /
- * Check if an object is made by a smith's special ability
- * @return エッセンス付加済みならばTRUEを返す
+ * @brief 鍛冶師のエッセンス付加済かを判定する
+ * @return エッセンス付加済か否か
  */
 bool ItemEntity::is_smith() const
 {
@@ -323,9 +322,8 @@ bool ItemEntity::is_smith() const
 }
 
 /*!
- * @brief アイテムが固定アーティファクトもしくはランダムアーティファクトであるかを返す /
- * Check if an object is artifact
- * @return 固定アーティファクトもしくはランダムアーティファクトならばtrueを返す
+ * @brief 固定アーティファクトもしくはランダムアーティファクトであるかを判定する
+ * @return 固定アーティファクトもしくはランダムアーティファクトか否か
  */
 bool ItemEntity::is_fixed_or_random_artifact() const
 {
@@ -333,9 +331,8 @@ bool ItemEntity::is_fixed_or_random_artifact() const
 }
 
 /*!
- * @brief アイテムが固定アーティファクトかを返す /
- * Check if an object is fixed artifact
- * @return 固定アーティファクトならばtrueを返す
+ * @brief 固定アーティファクトかを判定する
+ * @return 固定アーティファクトか否か
  */
 bool ItemEntity::is_fixed_artifact() const
 {
@@ -343,9 +340,8 @@ bool ItemEntity::is_fixed_artifact() const
 }
 
 /*!
- * @brief アイテムがランダムアーティファクトかを返す /
- * Check if an object is random artifact
- * @return ランダムアーティファクトならばtrueを返す
+ * @brief ランダムアーティファクトかを判定する
+ * @return ランダムアーティファクトか否か
  */
 bool ItemEntity::is_random_artifact() const
 {
@@ -353,9 +349,8 @@ bool ItemEntity::is_random_artifact() const
 }
 
 /*!
- * @brief アイテムが通常のアイテム(アーティファクト、エゴ、鍛冶師エッセンス付加いずれでもない)かを返す /
- * Check if an object is neither artifact, ego, nor 'smith' object
- * @return 通常のアイテムならばtrueを返す
+ * @brief 通常のアイテムかを返す
+ * @return アーティファクト、エゴ、鍛冶師エッセンス付加いずれでもないか、どれか1つであるか
  */
 bool ItemEntity::is_nameless() const
 {
@@ -383,9 +378,8 @@ bool ItemEntity::is_held_by_monster() const
 }
 
 /*
- * Determine if a given inventory item is "known"
- * Test One -- Check for special "known" tag
- * Test Two -- Check for "Easy Know" + "Aware"
+ * @brief 鑑定済かを判定する
+ * @return 鑑定済か否か
  */
 bool ItemEntity::is_known() const
 {
@@ -399,8 +393,8 @@ bool ItemEntity::is_fully_known() const
 }
 
 /*!
- * @brief 与えられたオブジェクトのベースアイテムが鑑定済かを返す / Determine if a given inventory item is "aware"
- * @return é\91\91å®\9aæ¸\88ã\81ªã\82\89true
+ * @brief ベースアイテムが鑑定済かを判定する
+ * @return é\91\91å®\9aæ¸\88ã\81\8bå\90¦ã\81\8b
  */
 bool ItemEntity::is_aware() const
 {
@@ -408,7 +402,8 @@ bool ItemEntity::is_aware() const
 }
 
 /*
- * Determine if a given inventory item is "tried"
+ * @brief ベースアイテムが試行済かを判定する
+ * @return 試行済か否か
  */
 bool ItemEntity::is_tried() const
 {
@@ -416,44 +411,39 @@ bool ItemEntity::is_tried() const
 }
 
 /*!
- * @brief アイテムが薬であるかを返す
- * @return オブジェクトが薬ならばtrueを返す
+ * @brief 薬であるかを判定する
+ * @return 薬か否か
  */
 bool ItemEntity::is_potion() const
 {
-    return this->bi_key.tval() == ItemKindType::POTION;
+    return this->bi_key.is(ItemKindType::POTION);
 }
 
 /*!
- * @brief アイテムをプレイヤーが読むことができるかを判定する /
- * Hook to determine if an object is readable
- * @return 読むことが可能ならばtrueを返す
+ * @brief 読めるアイテムかを判定する
+ * @return 読めるか否か
  */
 bool ItemEntity::is_readable() const
 {
-    const auto tval = this->bi_key.tval();
-    auto can_read = tval == ItemKindType::SCROLL;
-    can_read |= tval == ItemKindType::PARCHMENT;
+    auto can_read = this->is(ItemKindType::SCROLL);
+    can_read |= this->is(ItemKindType::PARCHMENT);
     can_read |= this->is_specific_artifact(FixedArtifactId::GHB);
     can_read |= this->is_specific_artifact(FixedArtifactId::POWER);
     return can_read;
 }
 
 /*!
- * @brief アイテムがランタンの燃料になるかどうかを判定する
- * An "item_tester_hook" for refilling lanterns
- * @return オブジェクトがランタンの燃料になるならばTRUEを返す
+ * @brief ランタンの燃料になるかを判定する
+ * @return ランタンの燃料になるか否か
  */
 bool ItemEntity::can_refill_lantern() const
 {
-    const auto tval = this->bi_key.tval();
-    return (tval == ItemKindType::FLASK) || (this->bi_key == BaseitemKey(ItemKindType::LITE, SV_LITE_LANTERN));
+    return this->is(ItemKindType::FLASK) || (this->bi_key == BaseitemKey(ItemKindType::LITE, SV_LITE_LANTERN));
 }
 
 /*!
- * @brief アイテムが松明に束ねられるかどうかを判定する
- * An "item_tester_hook" for refilling torches
- * @return オブジェクトが松明に束ねられるならばTRUEを返す
+ * @brief 松明に束ねられるかどうかを判定する
+ * @return 松明に束ねられるか否か
  */
 bool ItemEntity::can_refill_torch() const
 {
@@ -462,7 +452,7 @@ bool ItemEntity::can_refill_torch() const
 
 /*!
  * @brief 魔力充填が可能なアイテムかどうか判定する
- * @return é­\94å\8a\9bå\85\85å¡«ã\81\8cå\8f¯è\83½ã\81ªã\82\89ã\81°TRUEã\82\92è¿\94ã\81\99
+ * @return é­\94å\8a\9bå\85\85å¡«ã\81\8cå\8f¯è\83½ã\81\8bå\90¦ã\81\8b
  */
 bool ItemEntity::can_recharge() const
 {
@@ -470,8 +460,8 @@ bool ItemEntity::can_recharge() const
 }
 
 /*!
- * @brief 悪魔領域のグレーターデーモン召喚に利用可能な死体かどうかを返す。 / An "item_tester_hook" for offer
- * @return ç\94\9fè´\84ã\81«ä½¿ç\94¨å\8f¯è\83½ã\81ªæ­»ä½\93ã\81ªã\82\89ã\81°TRUEã\82\92è¿\94ã\81\99ã\80\82
+ * @brief 悪魔領域のグレーターデーモン召喚に利用可能な死体かどうかを判定する
+ * @return ç\94\9fè´\84ã\81«ä½¿ç\94¨å\8f¯è\83½ã\81ªæ­»ä½\93ã\81\8bå\90¦ã\81\8b
  */
 bool ItemEntity::is_offerable() const
 {
@@ -483,9 +473,8 @@ bool ItemEntity::is_offerable() const
 }
 
 /*!
- * @brief アイテムをプレイヤーが魔道具として発動できるかを判定する /
- * Hook to determine if an object is activatable
- * @return 魔道具として発動可能ならばTRUEを返す
+ * @brief 魔道具として発動できるかを判定する
+ * @return 発動可能か否か
  */
 bool ItemEntity::is_activatable() const
 {
@@ -498,7 +487,7 @@ bool ItemEntity::is_activatable() const
 }
 
 /*!
- * @brief アイテムが燃料として使えるかを判定する
+ * @brief 燃料として使えるかを判定する
  * @return 燃料か否か
  */
 bool ItemEntity::is_fuel() const
@@ -510,7 +499,7 @@ bool ItemEntity::is_fuel() const
 }
 
 /*!
- * @brief アイテムが魔法書かどうかを判定する
+ * @brief 魔法書かどうかを判定する
  * @return 魔法書か否か
  */
 bool ItemEntity::is_spell_book() const
@@ -519,7 +508,7 @@ bool ItemEntity::is_spell_book() const
 }
 
 /*!
- * @brief アイテムが同一の命中値上昇及びダメージ上昇があるかを判定する
+ * @brief 同一の命中値上昇及びダメージ上昇があるかを判定する
  * @return 同一修正か
  * @details 鍛冶師が篭手に殺戮エッセンスを付加した場合のみこの判定に意味がある
  */
@@ -541,7 +530,7 @@ bool ItemEntity::is_glove_same_temper(const ItemEntity *j_ptr) const
 }
 
 /*!
- * @brief ã\82¢ã\82¤ã\83\86ã\83 ã\81\8cã\80\8c\81¤ã\81®ï½\9eï½\9eã\80\8dã\81¨é\87\8dã\81­ã\82\89ã\82\8cã\82\8bã\81\8bã\82\92ä¸\80è\88¬ç\9a\84ã\81«å\88¤å®\9aã\81\99ã\82\8b
+ * @brief 「2つの~~」と重ねられるかを一般的に判定する
  * @return 重ねられるか
  * @details 個別のアイテムによっては別途条件があるが、それはこの関数では判定しない
  */
@@ -647,7 +636,7 @@ char ItemEntity::get_symbol() const
 
 /*!
  * @brief アイテム価格算出のメインルーチン
- * @return オブジェクトの判明している現価格
+ * @return 判明している現価格
  */
 int ItemEntity::get_price() const
 {
@@ -806,6 +795,21 @@ bool ItemEntity::is_inscribed() const
     return this->inscription != std::nullopt;
 }
 
+/*!
+ * @brief オブジェクトから発動効果構造体を取得する。
+ * @return 発動効果構造体 (なかったら無効イテレータ)
+ */
+std::vector<activation_type>::const_iterator ItemEntity::find_activation_info() const
+{
+    const auto index = this->get_activation_index();
+    return std::find_if(activation_info.begin(), activation_info.end(), [index](const auto &x) { return x.index == index; });
+}
+
+bool ItemEntity::has_activation() const
+{
+    return this->get_activation_index() != RandomArtActType::NONE;
+}
+
 BaseitemInfo &ItemEntity::get_baseitem() const
 {
     return baseitems_info[this->bi_id];
@@ -838,7 +842,7 @@ TrFlags ItemEntity::get_flags() const
 
     flags.set(this->art_flags);
     if (auto effect = Smith::object_effect(this); effect) {
-        auto tr_flags = Smith::get_effect_tr_flags(effect.value());
+        auto tr_flags = Smith::get_effect_tr_flags(*effect);
         flags.set(tr_flags);
     }
 
@@ -877,7 +881,7 @@ TrFlags ItemEntity::get_flags_known() const
     }
 
     if (auto effect = Smith::object_effect(this); effect) {
-        auto tr_flags = Smith::get_effect_tr_flags(effect.value());
+        auto tr_flags = Smith::get_effect_tr_flags(*effect);
         flags.set(tr_flags);
     }
 
@@ -889,7 +893,95 @@ TrFlags ItemEntity::get_flags_known() const
 }
 
 /*!
- * @brief オブジェクトを鑑定済にする
+ * @brief 発動効果の記述を生成する (メインルーチン)
+ * @return 発動効果
+ */
+std::string ItemEntity::explain_activation() const
+{
+    const auto flags = this->get_flags();
+    if (flags.has_not(TR_ACTIVATE)) {
+        return _("なし", "nothing");
+    }
+
+    if (this->has_activation()) {
+        return this->build_activation_description();
+    }
+
+    const auto tval = this->bi_key.tval();
+    if (tval == ItemKindType::WHISTLE) {
+        return _("ペット呼び寄せ : 100+d100ターン毎", "call pet every 100+d100 turns");
+    }
+
+    if (tval == ItemKindType::CAPTURE) {
+        return _("モンスターを捕える、又は解放する。", "captures or releases a monster.");
+    }
+
+    return _("何も起きない", "Nothing");
+}
+
+std::string ItemEntity::build_timeout_description(const activation_type &act) const
+{
+    const auto constant = act.timeout.constant;
+    const auto dice = act.timeout.dice;
+    if (constant == 0 && dice == 0) {
+        return _("いつでも", "every turn");
+    }
+
+    if (constant >= 0) {
+        std::stringstream ss;
+        ss << _("", "every ");
+        if (constant > 0) {
+            ss << constant;
+            if (dice > 0) {
+                ss << '+';
+            }
+        }
+
+        if (dice > 0) {
+            ss << 'd' << dice;
+        }
+
+        ss << _(" ターン毎", " turns");
+        return ss.str();
+    }
+
+    std::stringstream ss;
+    switch (act.index) {
+    case RandomArtActType::BR_FIRE:
+        ss << _("", "every ") << (this->bi_key == BaseitemKey(ItemKindType::RING, SV_RING_FLAMES) ? 200 : 250) << _(" ターン毎", " turns");
+        return ss.str();
+    case RandomArtActType::BR_COLD:
+        ss << _("", "every ") << (this->bi_key == BaseitemKey(ItemKindType::RING, SV_RING_ICE) ? 200 : 250) << _(" ターン毎", " turns");
+        return ss.str();
+    case RandomArtActType::TERROR:
+        return _("3*(レベル+10) ターン毎", "every 3 * (level+10) turns");
+    case RandomArtActType::MURAMASA:
+        return _("確率50%で壊れる", "(destroyed 50%)");
+    default:
+        return "undefined";
+    }
+}
+
+/*!
+ * @brief 発動効果の記述を生成する(サブルーチン/汎用)
+ * @return 発動効果
+ */
+std::string ItemEntity::build_activation_description() const
+{
+    const auto it = this->find_activation_info();
+    if (it == activation_info.end()) {
+        return _("未定義", "something undefined");
+    }
+
+    const auto activation_description = this->build_activation_description(*it);
+    const auto timeout_description = this->build_timeout_description(*it);
+    std::stringstream ss;
+    ss << activation_description << _(" : ", " ") << timeout_description;
+    return ss.str();
+}
+
+/*!
+ * @brief 鑑定済にする
  */
 void ItemEntity::mark_as_known()
 {
@@ -900,7 +992,7 @@ void ItemEntity::mark_as_known()
 }
 
 /*!
- * @brief オブジェクトを試行済にする
+ * @brief 試行済にする
  */
 void ItemEntity::mark_as_tried()
 {
@@ -917,7 +1009,7 @@ void ItemEntity::mark_as_tried()
  */
 void ItemEntity::modify_ego_lite_flags(TrFlags &flags) const
 {
-    if (this->bi_key.tval() != ItemKindType::LITE) {
+    if (!this->bi_key.is(ItemKindType::LITE)) {
         return;
     }
 
@@ -939,3 +1031,114 @@ void ItemEntity::modify_ego_lite_flags(TrFlags &flags) const
         return;
     }
 }
+
+/*!
+ * @brief 発動効果IDを取得する
+ * @details いくつかのケースで定義されている発動効果から、
+ * 鍛冶師による付与>固定アーティファクト>エゴ>ランダムアーティファクト>ベースアイテムの優先順位で走査する
+ * @return 発動効果ID
+ */
+RandomArtActType ItemEntity::get_activation_index() const
+{
+    if (auto act_idx = Smith::object_activation(this); act_idx) {
+        return *act_idx;
+    }
+
+    if (this->is_fixed_artifact()) {
+        const auto &artifact = this->get_fixed_artifact();
+        if (artifact.flags.has(TR_ACTIVATE)) {
+            return artifact.act_idx;
+        }
+    }
+
+    if (this->is_ego()) {
+        const auto &ego = this->get_ego();
+        if (ego.flags.has(TR_ACTIVATE)) {
+            return ego.act_idx;
+        }
+    }
+
+    if (!this->is_random_artifact()) {
+        const auto &baseitem = this->get_baseitem();
+        if (baseitem.flags.has(TR_ACTIVATE)) {
+            return baseitem.act_idx;
+        }
+    }
+
+    return this->activation_id;
+}
+
+std::string ItemEntity::build_activation_description(const activation_type &act) const
+{
+    switch (act.index) {
+    case RandomArtActType::NONE:
+        return act.desc;
+    case RandomArtActType::BR_FIRE:
+        if (this->bi_key == BaseitemKey(ItemKindType::RING, SV_RING_FLAMES)) {
+            return _("火炎のブレス (200) と火への耐性", "breathe fire (200) and resist fire");
+        }
+
+        return act.desc;
+    case RandomArtActType::BR_COLD:
+        if (this->bi_key == BaseitemKey(ItemKindType::RING, SV_RING_ICE)) {
+            return _("冷気のブレス (200) と冷気への耐性", "breathe cold (200) and resist cold");
+        }
+
+        return act.desc;
+    case RandomArtActType::BR_DRAGON:
+        return this->build_activation_description_dragon_breath();
+    case RandomArtActType::AGGRAVATE:
+        if (this->is_specific_artifact(FixedArtifactId::HYOUSIGI)) {
+            return _("拍子木を打ちならす", "beat wooden clappers");
+        }
+
+        return act.desc;
+    case RandomArtActType::ACID_BALL_AND_RESISTANCE:
+        return _("アシッド・ボール (100) と酸への耐性", "ball of acid (100) and resist acid");
+    case RandomArtActType::FIRE_BALL_AND_RESISTANCE:
+        return _("ファイア・ボール (100) と火への耐性", "ball of fire (100) and resist fire");
+    case RandomArtActType::COLD_BALL_AND_RESISTANCE:
+        return _("アイス・ボール (100) と冷気への耐性", "ball of cold (100) and resist cold");
+    case RandomArtActType::ELEC_BALL_AND_RESISTANCE:
+        return _("サンダー・ボール (100) と電撃への耐性", "ball of elec (100) and resist elec");
+    case RandomArtActType::POIS_BALL_AND_RESISTANCE:
+        return _("ポイズン・ボール (100) と毒への耐性", "ball of poison (100) and resist elec");
+    case RandomArtActType::RESIST_ACID:
+        return _("一時的な酸への耐性", "temporary resist acid");
+    case RandomArtActType::RESIST_FIRE:
+        return _("一時的な火への耐性", "temporary resist fire");
+    case RandomArtActType::RESIST_COLD:
+        return _("一時的な冷気への耐性", "temporary resist cold");
+    case RandomArtActType::RESIST_ELEC:
+        return _("一時的な電撃への耐性", "temporary resist elec");
+    case RandomArtActType::RESIST_POIS:
+        return _("一時的な毒への耐性", "temporary resist elec");
+    default:
+        return act.desc;
+    }
+}
+
+/*!
+ * @brief 発動効果の記述を返す (ドラゴンブレス)
+ * @return 発動効果
+ */
+std::string ItemEntity::build_activation_description_dragon_breath() const
+{
+    std::stringstream ss;
+    ss << _("", "breathe ");
+    auto n = 0;
+    const auto flags = this->get_flags();
+    for (auto i = 0; dragonbreath_info[i].flag != 0; i++) {
+        if (flags.has(dragonbreath_info[i].flag)) {
+            if (n > 0) {
+                ss << _("、", ", ");
+            }
+
+            ss << dragonbreath_info[i].name;
+            n++;
+        }
+    }
+
+    ss << _("のブレス(250)", " (250)");
+    return ss.str();
+}