2 * @brief ベースアイテム情報の構造体 / Information about object "kinds", including player knowledge.
6 * ゲーム進行用のセーブファイル上では aware と tried のみ保存対象とすること。と英文ではあるが実際はもっとある様子である。 /
7 * Only "aware" and "tried" are saved in the savefile
10 #include "system/baseitem-info.h"
11 #include "object/tval-types.h"
12 #include "sv-definition/sv-armor-types.h"
13 #include "sv-definition/sv-bow-types.h"
14 #include "sv-definition/sv-food-types.h"
15 #include "sv-definition/sv-lite-types.h"
16 #include "sv-definition/sv-protector-types.h"
17 #include "sv-definition/sv-rod-types.h"
18 #include "sv-definition/sv-weapon-types.h"
19 #include "system/angband-exceptions.h"
21 #include <unordered_map>
24 constexpr auto ITEM_NOT_BOW = "This item is not a bow!";
25 constexpr auto ITEM_NOT_ROD = "This item is not a rod!";
26 constexpr auto ITEM_NOT_LITE = "This item is not a lite!";
29 bool BaseitemKey::operator==(const BaseitemKey &other) const
31 return (this->type_value == other.type_value) && (this->subtype_value == other.subtype_value);
34 // @details type_valueに大小があればそれを判定し、同一ならばsubtype_valueの大小を判定する.
35 bool BaseitemKey::operator<(const BaseitemKey &other) const
37 if (this->type_value < other.type_value) {
41 if (this->type_value > other.type_value) {
45 return this->subtype_value < other.subtype_value;
48 ItemKindType BaseitemKey::tval() const
50 return this->type_value;
53 std::optional<int> BaseitemKey::sval() const
55 return this->subtype_value;
58 bool BaseitemKey::is(ItemKindType tval) const
60 return this->type_value == tval;
64 * @brief 射撃武器に対応する矢/弾薬のベースアイテムIDを返す
65 * @return 対応する矢/弾薬のベースアイテムID
67 ItemKindType BaseitemKey::get_arrow_kind() const
69 if ((this->type_value != ItemKindType::BOW) || !this->subtype_value) {
70 THROW_EXCEPTION(std::logic_error, ITEM_NOT_BOW);
73 switch (*this->subtype_value) {
75 return ItemKindType::SHOT;
79 return ItemKindType::ARROW;
82 return ItemKindType::BOLT;
85 return ItemKindType::NO_AMMO;
87 return ItemKindType::NONE;
91 bool BaseitemKey::is_spell_book() const
93 switch (this->type_value) {
94 case ItemKindType::LIFE_BOOK:
95 case ItemKindType::SORCERY_BOOK:
96 case ItemKindType::NATURE_BOOK:
97 case ItemKindType::CHAOS_BOOK:
98 case ItemKindType::DEATH_BOOK:
99 case ItemKindType::TRUMP_BOOK:
100 case ItemKindType::ARCANE_BOOK:
101 case ItemKindType::CRAFT_BOOK:
102 case ItemKindType::DEMON_BOOK:
103 case ItemKindType::CRUSADE_BOOK:
104 case ItemKindType::MUSIC_BOOK:
105 case ItemKindType::HISSATSU_BOOK:
106 case ItemKindType::HEX_BOOK:
113 bool BaseitemKey::is_high_level_book() const
115 if (!this->is_spell_book()) {
119 if (this->type_value == ItemKindType::ARCANE_BOOK) {
123 return this->subtype_value >= 2;
126 bool BaseitemKey::is_melee_weapon() const
128 switch (this->type_value) {
129 case ItemKindType::POLEARM:
130 case ItemKindType::SWORD:
131 case ItemKindType::DIGGING:
132 case ItemKindType::HAFTED:
139 bool BaseitemKey::is_ammo() const
141 switch (this->type_value) {
142 case ItemKindType::SHOT:
143 case ItemKindType::ARROW:
144 case ItemKindType::BOLT:
152 * @brief 未鑑定名を持つか否かの判定
153 * @details FOODはキノコが該当する
155 bool BaseitemKey::has_unidentified_name() const
157 switch (this->type_value) {
158 case ItemKindType::AMULET:
159 case ItemKindType::RING:
160 case ItemKindType::STAFF:
161 case ItemKindType::WAND:
162 case ItemKindType::ROD:
163 case ItemKindType::SCROLL:
164 case ItemKindType::POTION:
166 case ItemKindType::FOOD:
167 return this->is_mushrooms();
173 bool BaseitemKey::can_recharge() const
175 switch (this->type_value) {
176 case ItemKindType::STAFF:
177 case ItemKindType::WAND:
178 case ItemKindType::ROD:
185 bool BaseitemKey::is_wand_rod() const
187 switch (this->type_value) {
188 case ItemKindType::WAND:
189 case ItemKindType::ROD:
196 bool BaseitemKey::is_wand_staff() const
198 switch (this->type_value) {
199 case ItemKindType::WAND:
200 case ItemKindType::STAFF:
207 bool BaseitemKey::is_protector() const
209 switch (this->type_value) {
210 case ItemKindType::BOOTS:
211 case ItemKindType::GLOVES:
212 case ItemKindType::HELM:
213 case ItemKindType::CROWN:
214 case ItemKindType::SHIELD:
215 case ItemKindType::CLOAK:
216 case ItemKindType::SOFT_ARMOR:
217 case ItemKindType::HARD_ARMOR:
218 case ItemKindType::DRAG_ARMOR:
225 bool BaseitemKey::can_be_aura_protector() const
227 switch (this->type_value) {
228 case ItemKindType::CLOAK:
229 case ItemKindType::SOFT_ARMOR:
230 case ItemKindType::HARD_ARMOR:
237 bool BaseitemKey::is_wearable() const
239 switch (this->type_value) {
240 case ItemKindType::BOW:
241 case ItemKindType::DIGGING:
242 case ItemKindType::HAFTED:
243 case ItemKindType::POLEARM:
244 case ItemKindType::SWORD:
245 case ItemKindType::BOOTS:
246 case ItemKindType::GLOVES:
247 case ItemKindType::HELM:
248 case ItemKindType::CROWN:
249 case ItemKindType::SHIELD:
250 case ItemKindType::CLOAK:
251 case ItemKindType::SOFT_ARMOR:
252 case ItemKindType::HARD_ARMOR:
253 case ItemKindType::DRAG_ARMOR:
254 case ItemKindType::LITE:
255 case ItemKindType::AMULET:
256 case ItemKindType::RING:
257 case ItemKindType::CARD:
264 bool BaseitemKey::is_weapon() const
266 switch (this->type_value) {
267 case ItemKindType::BOW:
268 case ItemKindType::DIGGING:
269 case ItemKindType::HAFTED:
270 case ItemKindType::POLEARM:
271 case ItemKindType::SWORD:
278 bool BaseitemKey::is_equipement() const
280 return this->is_wearable() || this->is_ammo();
283 bool BaseitemKey::is_melee_ammo() const
285 switch (this->type_value) {
286 case ItemKindType::HAFTED:
287 case ItemKindType::POLEARM:
288 case ItemKindType::DIGGING:
289 case ItemKindType::BOLT:
290 case ItemKindType::ARROW:
291 case ItemKindType::SHOT:
293 case ItemKindType::SWORD:
294 return this->subtype_value != SV_POISON_NEEDLE;
300 bool BaseitemKey::is_orthodox_melee_weapon() const
302 switch (this->type_value) {
303 case ItemKindType::HAFTED:
304 case ItemKindType::POLEARM:
305 case ItemKindType::DIGGING:
307 case ItemKindType::SWORD:
308 return this->subtype_value != SV_POISON_NEEDLE;
314 bool BaseitemKey::is_broken_weapon() const
316 if (this->type_value != ItemKindType::SWORD) {
320 if (!this->subtype_value) {
324 switch (*this->subtype_value) {
325 case SV_BROKEN_DAGGER:
326 case SV_BROKEN_SWORD:
333 bool BaseitemKey::is_throwable() const
335 switch (this->type_value) {
336 case ItemKindType::DIGGING:
337 case ItemKindType::HAFTED:
338 case ItemKindType::POLEARM:
339 case ItemKindType::SWORD:
346 bool BaseitemKey::is_wieldable_in_etheir_hand() const
348 switch (this->type_value) {
349 case ItemKindType::DIGGING:
350 case ItemKindType::HAFTED:
351 case ItemKindType::POLEARM:
352 case ItemKindType::SWORD:
353 case ItemKindType::SHIELD:
354 case ItemKindType::CAPTURE:
355 case ItemKindType::CARD:
362 bool BaseitemKey::is_rare() const
364 static const std::unordered_map<ItemKindType, const std::set<int>> rare_table = {
365 { ItemKindType::HAFTED, { SV_MACE_OF_DISRUPTION, SV_WIZSTAFF } },
366 { ItemKindType::POLEARM, { SV_SCYTHE_OF_SLICING, SV_DEATH_SCYTHE } },
367 { ItemKindType::SWORD, { SV_BLADE_OF_CHAOS, SV_DIAMOND_EDGE, SV_POISON_NEEDLE, SV_HAYABUSA } },
368 { ItemKindType::SHIELD, { SV_DRAGON_SHIELD, SV_MIRROR_SHIELD } },
369 { ItemKindType::HELM, { SV_DRAGON_HELM } },
370 { ItemKindType::BOOTS, { SV_PAIR_OF_DRAGON_GREAVE } },
371 { ItemKindType::CLOAK, { SV_ELVEN_CLOAK, SV_ETHEREAL_CLOAK, SV_SHADOW_CLOAK, SV_MAGIC_RESISTANCE_CLOAK } },
372 { ItemKindType::GLOVES, { SV_SET_OF_DRAGON_GLOVES } },
373 { ItemKindType::SOFT_ARMOR, { SV_KUROSHOUZOKU, SV_ABUNAI_MIZUGI } },
374 { ItemKindType::HARD_ARMOR, { SV_MITHRIL_CHAIN_MAIL, SV_MITHRIL_PLATE_MAIL, SV_ADAMANTITE_PLATE_MAIL } },
375 { ItemKindType::DRAG_ARMOR, { /* Any */ } },
378 if (!this->subtype_value) {
382 if (auto it = rare_table.find(this->type_value); it != rare_table.end()) {
383 const auto &svals = it->second;
384 return svals.empty() || (svals.find(*this->subtype_value) != svals.end());
390 short BaseitemKey::get_bow_energy() const
392 if ((this->type_value != ItemKindType::BOW) || !this->subtype_value) {
393 THROW_EXCEPTION(std::logic_error, ITEM_NOT_BOW);
396 switch (*this->subtype_value) {
410 int BaseitemKey::get_arrow_magnification() const
412 if ((this->type_value != ItemKindType::BOW) || !this->subtype_value) {
413 THROW_EXCEPTION(std::logic_error, ITEM_NOT_BOW);
416 switch (*this->subtype_value) {
431 bool BaseitemKey::is_aiming_rod() const
433 if ((this->type_value != ItemKindType::ROD) || !this->subtype_value) {
434 THROW_EXCEPTION(std::logic_error, ITEM_NOT_ROD);
437 switch (*this->subtype_value) {
438 case SV_ROD_TELEPORT_AWAY:
439 case SV_ROD_DISARMING:
441 case SV_ROD_SLEEP_MONSTER:
442 case SV_ROD_SLOW_MONSTER:
443 case SV_ROD_HYPODYNAMIA:
444 case SV_ROD_POLYMORPH:
445 case SV_ROD_ACID_BOLT:
446 case SV_ROD_ELEC_BOLT:
447 case SV_ROD_FIRE_BOLT:
448 case SV_ROD_COLD_BOLT:
449 case SV_ROD_ACID_BALL:
450 case SV_ROD_ELEC_BALL:
451 case SV_ROD_FIRE_BALL:
452 case SV_ROD_COLD_BALL:
453 case SV_ROD_STONE_TO_MUD:
460 bool BaseitemKey::is_lite_requiring_fuel() const
462 if ((this->type_value != ItemKindType::LITE) || !this->subtype_value) {
463 THROW_EXCEPTION(std::logic_error, ITEM_NOT_LITE);
466 switch (*this->subtype_value) {
468 case SV_LITE_LANTERN:
475 bool BaseitemKey::is_junk() const
477 switch (this->type_value) {
478 case ItemKindType::SKELETON:
479 case ItemKindType::BOTTLE:
480 case ItemKindType::JUNK:
481 case ItemKindType::STATUE:
488 bool BaseitemKey::is_armour() const
490 switch (this->type_value) {
491 case ItemKindType::SOFT_ARMOR:
492 case ItemKindType::HARD_ARMOR:
493 case ItemKindType::DRAG_ARMOR:
500 bool BaseitemKey::is_cross_bow() const
502 if ((this->type_value != ItemKindType::BOW) || !this->subtype_value) {
506 switch (*this->subtype_value) {
515 bool BaseitemKey::refuse_enchant_weapon() const
517 return *this == BaseitemKey(ItemKindType::SWORD, SV_POISON_NEEDLE);
521 * @brief ベースアイテムが発動効果を持つ時、その記述を生成する
524 std::string BaseitemKey::explain_activation() const
526 switch (this->type_value) {
527 case ItemKindType::WHISTLE:
528 return _("ペット呼び寄せ : 100+d100ターン毎", "call pet every 100+d100 turns");
529 case ItemKindType::CAPTURE:
530 return _("モンスターを捕える、又は解放する。", "captures or releases a monster.");
532 return _("何も起きない", "Nothing");
536 bool BaseitemKey::is_mushrooms() const
538 if (!this->subtype_value) {
542 switch (*this->subtype_value) {
544 case SV_FOOD_BLINDNESS:
545 case SV_FOOD_PARANOIA:
546 case SV_FOOD_CONFUSION:
547 case SV_FOOD_HALLUCINATION:
548 case SV_FOOD_PARALYSIS:
549 case SV_FOOD_WEAKNESS:
550 case SV_FOOD_SICKNESS:
551 case SV_FOOD_STUPIDITY:
552 case SV_FOOD_NAIVETY:
553 case SV_FOOD_UNHEALTH:
554 case SV_FOOD_DISEASE:
555 case SV_FOOD_CURE_POISON:
556 case SV_FOOD_CURE_BLINDNESS:
557 case SV_FOOD_CURE_PARANOIA:
558 case SV_FOOD_CURE_CONFUSION:
559 case SV_FOOD_CURE_SERIOUS:
560 case SV_FOOD_RESTORE_STR:
561 case SV_FOOD_RESTORE_CON:
562 case SV_FOOD_RESTORING:
569 BaseitemInfo::BaseitemInfo()
570 : bi_key(ItemKindType::NONE)
575 * @brief 最初から簡易な名称が明らかなベースアイテムにその旨のフラグを立てる
577 void BaseitemInfo::decide_easy_know()
579 switch (this->bi_key.tval()) {
580 case ItemKindType::LIFE_BOOK:
581 case ItemKindType::SORCERY_BOOK:
582 case ItemKindType::NATURE_BOOK:
583 case ItemKindType::CHAOS_BOOK:
584 case ItemKindType::DEATH_BOOK:
585 case ItemKindType::TRUMP_BOOK:
586 case ItemKindType::ARCANE_BOOK:
587 case ItemKindType::CRAFT_BOOK:
588 case ItemKindType::DEMON_BOOK:
589 case ItemKindType::CRUSADE_BOOK:
590 case ItemKindType::MUSIC_BOOK:
591 case ItemKindType::HISSATSU_BOOK:
592 case ItemKindType::HEX_BOOK:
593 case ItemKindType::FLASK:
594 case ItemKindType::JUNK:
595 case ItemKindType::BOTTLE:
596 case ItemKindType::SKELETON:
597 case ItemKindType::SPIKE:
598 case ItemKindType::WHISTLE:
599 case ItemKindType::FOOD:
600 case ItemKindType::POTION:
601 case ItemKindType::SCROLL:
602 case ItemKindType::ROD:
603 case ItemKindType::STATUE:
604 case ItemKindType::PARCHMENT:
605 this->easy_know = true;
608 this->easy_know = false;
614 * @brief オブジェクトを試行済にする
616 void BaseitemInfo::mark_as_tried()
621 std::vector<BaseitemInfo> baseitems_info;