2 * @file item-entity.cpp
3 * @brief アイテム実体とそれにまつわる判定処理群
6 * @details オブジェクトの状態を変更するメソッドは道半ば
9 #include "system/item-entity.h"
10 #include "artifact/fixed-art-types.h"
11 #include "artifact/random-art-effects.h"
12 #include "monster-race/monster-race.h"
13 #include "object-enchant/activation-info-table.h"
14 #include "object-enchant/dragon-breaths-table.h"
15 #include "object-enchant/item-feeling.h"
16 #include "object-enchant/object-curse.h"
17 #include "object-enchant/special-object-flags.h"
18 #include "object/object-value.h"
19 #include "object/tval-types.h"
20 #include "smith/object-smith.h"
21 #include "sv-definition/sv-lite-types.h"
22 #include "sv-definition/sv-other-types.h"
23 #include "sv-definition/sv-weapon-types.h"
24 #include "system/artifact-type-definition.h"
25 #include "system/baseitem-info.h"
26 #include "system/monster-race-info.h"
27 #include "term/term-color-types.h"
28 #include "util/bit-flags-calculator.h"
29 #include "util/enum-converter.h"
30 #include "util/string-processor.h"
33 ItemEntity::ItemEntity()
34 : bi_key(BaseitemKey(ItemKindType::NONE))
35 , fixed_artifact_idx(FixedArtifactId::NONE)
41 * Wipe an object clean.
43 void ItemEntity::wipe()
50 * Wipe an object clean.
51 * @param j_ptr 複製元のオブジェクトの構造体参照ポインタ
53 void ItemEntity::copy_from(const ItemEntity *j_ptr)
59 * @brief アイテム構造体にベースアイテムを作成する
60 * @param player_ptr プレイヤーへの参照ポインタ
61 * @param bi_id 新たに作成したいベースアイテム情報のID
63 void ItemEntity::prep(short new_bi_id)
65 const auto &baseitem = baseitems_info[new_bi_id];
66 auto old_stack_idx = this->stack_idx;
68 this->stack_idx = old_stack_idx;
69 this->bi_id = new_bi_id;
70 this->bi_key = baseitem.bi_key;
71 this->pval = baseitem.pval;
73 this->weight = baseitem.weight;
74 this->to_h = baseitem.to_h;
75 this->to_d = baseitem.to_d;
76 this->to_a = baseitem.to_a;
77 this->ac = baseitem.ac;
78 this->dd = baseitem.dd;
79 this->ds = baseitem.ds;
81 if (baseitem.act_idx > RandomArtActType::NONE) {
82 this->activation_id = baseitem.act_idx;
85 if (this->get_baseitem().cost <= 0) {
86 this->ident |= (IDENT_BROKEN);
89 if (baseitem.gen_flags.has(ItemGenerationTraitType::CURSED)) {
90 this->curse_flags.set(CurseTraitType::CURSED);
93 if (baseitem.gen_flags.has(ItemGenerationTraitType::HEAVY_CURSE)) {
94 this->curse_flags.set(CurseTraitType::HEAVY_CURSE);
97 if (baseitem.gen_flags.has(ItemGenerationTraitType::PERMA_CURSE)) {
98 this->curse_flags.set(CurseTraitType::PERMA_CURSE);
101 if (baseitem.gen_flags.has(ItemGenerationTraitType::RANDOM_CURSE0)) {
102 this->curse_flags.set(get_curse(0, this));
105 if (baseitem.gen_flags.has(ItemGenerationTraitType::RANDOM_CURSE1)) {
106 this->curse_flags.set(get_curse(1, this));
109 if (baseitem.gen_flags.has(ItemGenerationTraitType::RANDOM_CURSE2)) {
110 this->curse_flags.set(get_curse(2, this));
115 * @brief アイテムが武器として装備できるかどうかを返す / Check if an object is weapon (including bows)
116 * @return 武器として使えるならばtrueを返す
118 bool ItemEntity::is_weapon() const
120 return this->bi_key.is_weapon();
124 * @brief アイテムが武器や矢弾として使用できるかを返す
125 * @return 武器や矢弾として使えるならばtrueを返す
127 bool ItemEntity::is_weapon_ammo() const
129 return this->is_weapon() || this->is_ammo();
133 * @brief アイテムが武器、防具、矢弾として使用できるかを返す / Check if an object is weapon, armour or ammo
134 * @return 武器、防具、矢弾として使えるならばtrueを返す
136 bool ItemEntity::is_weapon_armour_ammo() const
138 return this->is_weapon_ammo() || this->is_protector();
142 * @brief アイテムが近接武器として装備できるかを返す / Melee weapons
143 * @return 近接武器として使えるならばtrueを返す
145 bool ItemEntity::is_melee_weapon() const
147 return this->bi_key.is_melee_weapon();
151 * @brief エッセンスの付加可能な武器や矢弾かを返す
152 * @return エッセンスの付加可能な武器か矢弾ならばtrueを返す。
154 bool ItemEntity::is_melee_ammo() const
156 return this->bi_key.is_melee_ammo();
160 * @brief アイテムが装備可能であるかを返す / Wearable including all weapon, all armour, bow, light source, amulet, and ring
161 * @return 装備可能ならばTRUEを返す
163 bool ItemEntity::is_wearable() const
165 return this->bi_key.is_wearable();
169 * @brief アイテムが装備品であるかを返す(ItemEntity::is_wearableに矢弾を含む) / Equipment including all wearable objects and ammo
170 * @return 装備品ならばtrueを返す
172 bool ItemEntity::is_equipment() const
174 return this->bi_key.is_equipement();
178 * @brief 武器匠の「武器」鑑定対象になるかを判定する。/ Hook to specify "weapon"
179 * @return 対象になるならtrueを返す。
181 bool ItemEntity::is_orthodox_melee_weapons() const
183 return this->bi_key.is_orthodox_melee_weapon();
187 * @brief 修復対象となる壊れた武器かを判定する。 / Hook to specify "broken weapon"
188 * @return 修復対象になるならTRUEを返す。
190 bool ItemEntity::is_broken_weapon() const
192 return this->bi_key.is_broken_weapon();
196 * @brief アイテムが投射可能な武器かどうかを返す。
197 * @return 投射可能な武器ならばtrue
199 bool ItemEntity::is_throwable() const
201 return this->bi_key.is_throwable();
205 * @brief アイテムがどちらの手にも装備できる武器かどうかの判定
206 * @return 左右両方の手で装備できるならばtrueを返す。
208 bool ItemEntity::is_wieldable_in_etheir_hand() const
210 return this->bi_key.is_wieldable_in_etheir_hand();
214 * @brief アイテムが強化不能武器であるかを返す / Poison needle can not be enchanted
215 * @return 強化不能ならばtrueを返す
217 bool ItemEntity::refuse_enchant_weapon() const
219 return this->bi_key == BaseitemKey(ItemKindType::SWORD, SV_POISON_NEEDLE);
223 * @brief アイテムが強化可能武器であるかを返す /
224 * Check if an object is weapon (including bows and ammo) and allows enchantment
225 * @return 強化可能ならばtrueを返す
227 bool ItemEntity::allow_enchant_weapon() const
229 return this->is_weapon_ammo() && !this->refuse_enchant_weapon();
233 * @brief アイテムが強化可能な近接武器であるかを返す /
234 * Check if an object is melee weapon and allows enchantment
235 * @return 強化可能な近接武器ならばtrueを返す
237 bool ItemEntity::allow_enchant_melee_weapon() const
239 return this->is_melee_weapon() && !this->refuse_enchant_weapon();
243 * @brief アイテムが両手持ち可能な武器かを返す /
244 * Check if an object is melee weapon and allows wielding with two-hands
245 * @return 両手持ち可能ならばTRUEを返す
247 bool ItemEntity::allow_two_hands_wielding() const
249 return this->is_melee_weapon() && ((this->weight > 99) || (this->bi_key.tval() == ItemKindType::POLEARM));
253 * @brief アイテムが矢弾として使用できるかどうかを返す / Check if an object is ammo
254 * @return 矢弾として使えるならばtrueを返す
256 bool ItemEntity::is_ammo() const
258 return this->bi_key.is_ammo();
262 * @brief 対象のアイテムが矢やクロスボウの矢の材料になるかを返す。/
263 * Hook to determine if an object is contertible in an arrow/bolt
264 * @return 材料にできるならtrueを返す
266 bool ItemEntity::is_convertible() const
268 const auto tval = this->bi_key.tval();
269 auto is_convertible = (tval == ItemKindType::JUNK) || (tval == ItemKindType::SKELETON);
270 is_convertible |= this->bi_key == BaseitemKey(ItemKindType::CORPSE, SV_SKELETON);
271 return is_convertible;
274 bool ItemEntity::is_lance() const
276 auto is_lance = this->bi_key == BaseitemKey(ItemKindType::POLEARM, SV_LANCE);
277 is_lance |= this->bi_key == BaseitemKey(ItemKindType::POLEARM, SV_HEAVY_LANCE);
282 * @brief アイテムが防具として装備できるかどうかを返す
283 * @return 防具として装備できるならばtrueを返す
285 bool ItemEntity::is_protector() const
287 return this->bi_key.is_protector();
291 * @brief アイテムがオーラを纏える防具かどうかを返す
292 * @return オーラを纏えるならばtrueを返す
294 bool ItemEntity::can_be_aura_protector() const
296 return this->bi_key.can_be_aura_protector();
300 * @brief アイテムがレアアイテムかどうかを返す /
301 * Rare weapons/aromors including Blade of Chaos, Dragon armors, etc.
302 * @return レアアイテムならばTRUEを返す
304 bool ItemEntity::is_rare() const
306 return this->bi_key.is_rare();
310 * @brief アイテムがエゴアイテムかどうかを返す
311 * @return エゴアイテムならばtrueを返す
313 bool ItemEntity::is_ego() const
315 return this->ego_idx != EgoType::NONE;
319 * @brief アイテムが鍛冶師のエッセンス付加済みかを返す /
320 * Check if an object is made by a smith's special ability
321 * @return エッセンス付加済みならばTRUEを返す
323 bool ItemEntity::is_smith() const
325 return Smith::object_effect(this) || Smith::object_activation(this);
329 * @brief アイテムが固定アーティファクトもしくはランダムアーティファクトであるかを返す /
330 * Check if an object is artifact
331 * @return 固定アーティファクトもしくはランダムアーティファクトならばtrueを返す
333 bool ItemEntity::is_fixed_or_random_artifact() const
335 return this->is_fixed_artifact() || this->randart_name;
339 * @brief アイテムが固定アーティファクトかを返す /
340 * Check if an object is fixed artifact
341 * @return 固定アーティファクトならばtrueを返す
343 bool ItemEntity::is_fixed_artifact() const
345 return !this->is_specific_artifact(FixedArtifactId::NONE);
349 * @brief アイテムがランダムアーティファクトかを返す /
350 * Check if an object is random artifact
351 * @return ランダムアーティファクトならばtrueを返す
353 bool ItemEntity::is_random_artifact() const
355 return this->is_fixed_or_random_artifact() && !this->is_fixed_artifact();
359 * @brief アイテムが通常のアイテム(アーティファクト、エゴ、鍛冶師エッセンス付加いずれでもない)かを返す /
360 * Check if an object is neither artifact, ego, nor 'smith' object
361 * @return 通常のアイテムならばtrueを返す
363 bool ItemEntity::is_nameless() const
365 return !this->is_fixed_or_random_artifact() && !this->is_ego() && !this->is_smith();
368 bool ItemEntity::is_valid() const
370 return this->bi_id != 0;
373 bool ItemEntity::is_broken() const
375 return any_bits(this->ident, IDENT_BROKEN);
378 bool ItemEntity::is_cursed() const
380 return this->curse_flags.any();
383 bool ItemEntity::is_held_by_monster() const
385 return this->held_m_idx != 0;
389 * Determine if a given inventory item is "known"
390 * Test One -- Check for special "known" tag
391 * Test Two -- Check for "Easy Know" + "Aware"
393 bool ItemEntity::is_known() const
395 const auto &baseitem = this->get_baseitem();
396 return any_bits(this->ident, IDENT_KNOWN) || (baseitem.easy_know && baseitem.aware);
399 bool ItemEntity::is_fully_known() const
401 return any_bits(this->ident, IDENT_FULL_KNOWN);
405 * @brief 与えられたオブジェクトのベースアイテムが鑑定済かを返す / Determine if a given inventory item is "aware"
408 bool ItemEntity::is_aware() const
410 return this->get_baseitem().aware;
414 * Determine if a given inventory item is "tried"
416 bool ItemEntity::is_tried() const
418 return this->get_baseitem().tried;
422 * @brief アイテムが薬であるかを返す
423 * @return オブジェクトが薬ならばtrueを返す
425 bool ItemEntity::is_potion() const
427 return this->bi_key.tval() == ItemKindType::POTION;
431 * @brief アイテムをプレイヤーが読むことができるかを判定する /
432 * Hook to determine if an object is readable
433 * @return 読むことが可能ならばtrueを返す
435 bool ItemEntity::is_readable() const
437 const auto tval = this->bi_key.tval();
438 auto can_read = tval == ItemKindType::SCROLL;
439 can_read |= tval == ItemKindType::PARCHMENT;
440 can_read |= this->is_specific_artifact(FixedArtifactId::GHB);
441 can_read |= this->is_specific_artifact(FixedArtifactId::POWER);
446 * @brief アイテムがランタンの燃料になるかどうかを判定する
447 * An "item_tester_hook" for refilling lanterns
448 * @return オブジェクトがランタンの燃料になるならばTRUEを返す
450 bool ItemEntity::can_refill_lantern() const
452 const auto tval = this->bi_key.tval();
453 return (tval == ItemKindType::FLASK) || (this->bi_key == BaseitemKey(ItemKindType::LITE, SV_LITE_LANTERN));
457 * @brief アイテムが松明に束ねられるかどうかを判定する
458 * An "item_tester_hook" for refilling torches
459 * @return オブジェクトが松明に束ねられるならばTRUEを返す
461 bool ItemEntity::can_refill_torch() const
463 return this->bi_key == BaseitemKey(ItemKindType::LITE, SV_LITE_TORCH);
467 * @brief 魔力充填が可能なアイテムかどうか判定する
468 * @return 魔力充填が可能ならばTRUEを返す
470 bool ItemEntity::can_recharge() const
472 return this->bi_key.can_recharge();
476 * @brief 悪魔領域のグレーターデーモン召喚に利用可能な死体かどうかを返す。 / An "item_tester_hook" for offer
477 * @return 生贄に使用可能な死体ならばTRUEを返す。
479 bool ItemEntity::is_offerable() const
481 if (this->bi_key != BaseitemKey(ItemKindType::CORPSE, SV_CORPSE)) {
485 return angband_strchr("pht", monraces_info[i2enum<MonsterRaceId>(this->pval)].d_char) != nullptr;
489 * @brief アイテムをプレイヤーが魔道具として発動できるかを判定する /
490 * Hook to determine if an object is activatable
491 * @return 魔道具として発動可能ならばTRUEを返す
493 bool ItemEntity::is_activatable() const
495 if (!this->is_known()) {
499 const auto flags = this->get_flags();
500 return flags.has(TR_ACTIVATE);
504 * @brief アイテムが燃料として使えるかを判定する
507 bool ItemEntity::is_fuel() const
509 auto is_fuel = this->bi_key == BaseitemKey(ItemKindType::LITE, SV_LITE_TORCH);
510 is_fuel |= this->bi_key == BaseitemKey(ItemKindType::LITE, SV_LITE_LANTERN);
511 is_fuel |= this->bi_key == BaseitemKey(ItemKindType::FLASK, SV_FLASK_OIL);
516 * @brief アイテムが魔法書かどうかを判定する
519 bool ItemEntity::is_spell_book() const
521 return this->bi_key.is_spell_book();
525 * @brief アイテムが同一の命中値上昇及びダメージ上昇があるかを判定する
527 * @details 鍛冶師が篭手に殺戮エッセンスを付加した場合のみこの判定に意味がある
529 bool ItemEntity::is_glove_same_temper(const ItemEntity *j_ptr) const
531 if (!this->is_smith() || !j_ptr->is_smith()) {
535 if (this->smith_hit != j_ptr->smith_hit) {
539 if (this->smith_damage != j_ptr->smith_damage) {
547 * @brief アイテムが「2つの~~」と重ねられるかを一般的に判定する
549 * @details 個別のアイテムによっては別途条件があるが、それはこの関数では判定しない
551 bool ItemEntity::can_pile(const ItemEntity *j_ptr) const
553 if (this->is_known() != j_ptr->is_known()) {
557 if (this->feeling != j_ptr->feeling) {
561 if (this->to_h != j_ptr->to_h) {
565 if (this->to_d != j_ptr->to_d) {
569 if (this->to_a != j_ptr->to_a) {
573 if (this->pval != j_ptr->pval) {
577 if (this->is_fixed_or_random_artifact() || j_ptr->is_fixed_or_random_artifact()) {
581 if (this->ego_idx != j_ptr->ego_idx) {
585 if (this->timeout || j_ptr->timeout) {
589 if (this->ac != j_ptr->ac) {
593 if (this->dd != j_ptr->dd) {
597 if (this->ds != j_ptr->ds) {
601 if (Smith::object_effect(this) != Smith::object_effect(j_ptr)) {
605 if (Smith::object_activation(this) != Smith::object_activation(j_ptr)) {
614 * @details 未鑑定名のあるアイテム (薬等)は、未鑑定名の割り当てられた色を返す
615 * 未鑑定名のないアイテム (魔法書等)はベースアイテム定義そのままを返す
616 * その中でモンスターの死体以外は、ベースアイテムの色を返す
617 * モンスターの死体は、元モンスターの色を返す
618 * 異常アイテム (「何か」)の場合、ベースアイテム定義に基づき黒を返す
620 TERM_COLOR ItemEntity::get_color() const
622 const auto &baseitem = this->get_baseitem();
623 const auto flavor = baseitem.flavor;
625 return baseitems_info[flavor].x_attr;
628 auto has_attr = !this->is_valid();
629 has_attr |= this->bi_key != BaseitemKey(ItemKindType::CORPSE, SV_CORPSE);
630 has_attr |= baseitem.x_attr != TERM_DARK;
632 return baseitem.x_attr;
635 return monraces_info[i2enum<MonsterRaceId>(this->pval)].x_attr;
639 * @brief アイテムシンボルを取得する
640 * @details 未鑑定名のないアイテム (魔法書等)はベースアイテム定義そのまま
641 * 未鑑定名のあるアイテム (薬等)は、未鑑定名の割り当てられたシンボル
642 * 以上について、設定で変更しているシンボルならばそれを、していないならば定義シンボルを返す
644 char ItemEntity::get_symbol() const
646 const auto &baseitem = this->get_baseitem();
647 const auto flavor = baseitem.flavor;
648 return flavor ? baseitems_info[flavor].x_char : baseitem.x_char;
652 * @brief アイテム価格算出のメインルーチン
653 * @return オブジェクトの判明している現価格
655 int ItemEntity::get_price() const
658 const auto is_worthless = this->is_broken() || this->is_cursed();
659 if (this->is_known()) {
664 value = object_value_real(this);
666 if (any_bits(this->ident, IDENT_SENSE) && is_worthless) {
670 value = this->get_baseitem_price();
673 if (this->discount) {
674 value -= (value * this->discount / 100L);
681 * @brief 未鑑定なベースアイテムの基本価格を返す
682 * @return オブジェクトの未鑑定価格
684 int ItemEntity::get_baseitem_price() const
686 if (this->is_aware()) {
687 return this->get_baseitem().cost;
690 switch (this->bi_key.tval()) {
691 case ItemKindType::FOOD:
693 case ItemKindType::POTION:
694 case ItemKindType::SCROLL:
696 case ItemKindType::STAFF:
698 case ItemKindType::WAND:
700 case ItemKindType::ROD:
702 case ItemKindType::RING:
703 case ItemKindType::AMULET:
705 case ItemKindType::FIGURINE:
706 return this->calc_figurine_value();
707 case ItemKindType::CAPTURE:
708 return this->calc_capture_value();
714 int ItemEntity::calc_figurine_value() const
716 auto figure_r_idx = i2enum<MonsterRaceId>(this->pval);
717 auto level = monraces_info[figure_r_idx].level;
723 return 1000 + (level - 20) * 150;
727 return 2500 + (level - 30) * 350;
731 return 6000 + (level - 40) * 800;
734 return 14000 + (level - 50) * 2000;
737 int ItemEntity::calc_capture_value() const
739 auto capture_r_idx = i2enum<MonsterRaceId>(this->pval);
740 if (!MonsterRace(capture_r_idx).is_valid()) {
744 return (monraces_info[capture_r_idx].level) * 50 + 1000;
747 bool ItemEntity::is_specific_artifact(FixedArtifactId id) const
749 return this->fixed_artifact_idx == id;
752 bool ItemEntity::has_unidentified_name() const
754 return this->bi_key.has_unidentified_name();
757 ItemKindType ItemEntity::get_arrow_kind() const
759 return this->bi_key.get_arrow_kind();
762 bool ItemEntity::is_wand_rod() const
764 return this->bi_key.is_wand_rod();
767 bool ItemEntity::is_wand_staff() const
769 return this->bi_key.is_wand_staff();
772 short ItemEntity::get_bow_energy() const
774 return this->bi_key.get_bow_energy();
777 int ItemEntity::get_arrow_magnification() const
779 return this->bi_key.get_arrow_magnification();
782 bool ItemEntity::is_aiming_rod() const
784 return this->bi_key.is_aiming_rod();
787 bool ItemEntity::is_lite_requiring_fuel() const
789 return this->bi_key.is_lite_requiring_fuel();
792 bool ItemEntity::is_junk() const
794 return this->bi_key.is_junk();
797 bool ItemEntity::is_armour() const
799 return this->bi_key.is_armour();
802 bool ItemEntity::is_cross_bow() const
804 return this->bi_key.is_cross_bow();
807 bool ItemEntity::is_inscribed() const
809 return this->inscription != std::nullopt;
813 * @brief オブジェクトから発動効果構造体を取得する。
814 * @return 発動効果構造体 (なかったら無効イテレータ)
816 std::vector<activation_type>::const_iterator ItemEntity::find_activation_info() const
818 const auto index = this->get_activation_index();
819 return std::find_if(activation_info.begin(), activation_info.end(), [index](const auto &x) { return x.index == index; });
822 bool ItemEntity::has_activation() const
824 return this->get_activation_index() != RandomArtActType::NONE;
827 BaseitemInfo &ItemEntity::get_baseitem() const
829 return baseitems_info[this->bi_id];
832 EgoItemDefinition &ItemEntity::get_ego() const
834 return egos_info.at(this->ego_idx);
837 ArtifactType &ItemEntity::get_fixed_artifact() const
839 return ArtifactsInfo::get_instance().get_artifact(this->fixed_artifact_idx);
842 TrFlags ItemEntity::get_flags() const
844 const auto &baseitem = this->get_baseitem();
845 auto flags = baseitem.flags;
847 if (this->is_fixed_artifact()) {
848 flags = this->get_fixed_artifact().flags;
851 if (this->is_ego()) {
852 const auto &ego = this->get_ego();
853 flags.set(ego.flags);
854 this->modify_ego_lite_flags(flags);
857 flags.set(this->art_flags);
858 if (auto effect = Smith::object_effect(this); effect) {
859 auto tr_flags = Smith::get_effect_tr_flags(*effect);
863 if (Smith::object_activation(this)) {
864 flags.set(TR_ACTIVATE);
870 TrFlags ItemEntity::get_flags_known() const
873 if (!this->is_aware()) {
877 const auto &baseitem = this->get_baseitem();
878 flags = baseitem.flags;
879 if (!this->is_known()) {
883 if (this->is_ego()) {
884 const auto &ego = this->get_ego();
885 flags.set(ego.flags);
886 this->modify_ego_lite_flags(flags);
889 if (this->is_fully_known()) {
890 if (this->is_fixed_artifact()) {
891 flags = this->get_fixed_artifact().flags;
894 flags.set(this->art_flags);
897 if (auto effect = Smith::object_effect(this); effect) {
898 auto tr_flags = Smith::get_effect_tr_flags(*effect);
902 if (Smith::object_activation(this)) {
903 flags.set(TR_ACTIVATE);
910 * @brief アイテムの発動効果名称を返す (ドラゴンブレス)
913 std::string ItemEntity::build_activation_description_dragon_breath() const
915 std::stringstream ss;
916 ss << _("", "breathe ");
918 const auto flags = this->get_flags();
919 for (auto i = 0; dragonbreath_info[i].flag != 0; i++) {
920 if (flags.has(dragonbreath_info[i].flag)) {
925 ss << dragonbreath_info[i].name;
930 ss << _("のブレス(250)", " (250)");
935 * @brief オブジェクトを鑑定済にする
937 void ItemEntity::mark_as_known()
939 this->feeling = FEEL_NONE;
940 this->ident &= ~(IDENT_SENSE);
941 this->ident &= ~(IDENT_EMPTY);
942 this->ident |= (IDENT_KNOWN);
946 * @brief オブジェクトを試行済にする
948 void ItemEntity::mark_as_tried()
950 this->get_baseitem().mark_as_tried();
954 * @brief エゴ光源のフラグを修正する
956 * 寿命のある光源で寿命が0ターンの時、光源エゴアイテムに起因するフラグは
957 * 灼熱エゴの火炎耐性を除き付与されないようにする。
959 * @param flags フラグ情報を受け取る配列
961 void ItemEntity::modify_ego_lite_flags(TrFlags &flags) const
963 if (this->bi_key.tval() != ItemKindType::LITE) {
967 if (!this->is_lite_requiring_fuel() || this->fuel != 0) {
971 switch (this->ego_idx) {
972 case EgoType::LITE_AURA_FIRE:
973 flags.reset(TR_SH_FIRE);
975 case EgoType::LITE_INFRA:
976 flags.reset(TR_INFRA);
978 case EgoType::LITE_EYE:
979 flags.reset({ TR_RES_BLIND, TR_SEE_INVIS });
987 * @brief オブジェクトから能力発動IDを取得する。
988 * @details いくつかのケースで定義されている発動効果から、
989 * 鍛冶師による付与>固定アーティファクト>エゴ>ランダムアーティファクト>ベースアイテムの優先順位で走査していく。
990 * @param o_ptr 対象のオブジェクト構造体ポインタ
993 RandomArtActType ItemEntity::get_activation_index() const
995 if (auto act_idx = Smith::object_activation(this); act_idx) {
999 if (this->is_fixed_artifact()) {
1000 const auto &artifact = this->get_fixed_artifact();
1001 if (artifact.flags.has(TR_ACTIVATE)) {
1002 return artifact.act_idx;
1006 if (this->is_ego()) {
1007 const auto &ego = this->get_ego();
1008 if (ego.flags.has(TR_ACTIVATE)) {
1013 if (!this->is_random_artifact()) {
1014 const auto &baseitem = this->get_baseitem();
1015 if (baseitem.flags.has(TR_ACTIVATE)) {
1016 return baseitem.act_idx;
1020 return this->activation_id;