• R/O
  • HTTP
  • SSH
  • HTTPS

hengbandosx: 提交

The master and develop branches track hengband.

OS X development happens on the macos-1-6-2, macos-2-2-1, and macos-develop branches.


Commit MetaInfo

修订版0527d34d28ea404d4b9b7d350a401b61a1adbed1 (tree)
时间2022-09-14 21:35:42
作者Eric Branlund <ebranlund@fast...>
CommiterEric Branlund

Log Message

Merge branch 'develop' into macos-develop

更改概述

差异

--- a/src/action/activation-execution.cpp
+++ b/src/action/activation-execution.cpp
@@ -55,7 +55,7 @@
5555 static void decide_activation_level(ae_type *ae_ptr)
5656 {
5757 if (ae_ptr->o_ptr->is_fixed_artifact()) {
58- ae_ptr->lev = a_info[enum2i(ae_ptr->o_ptr->fixed_artifact_idx)].level;
58+ ae_ptr->lev = a_info.at(ae_ptr->o_ptr->fixed_artifact_idx).level;
5959 return;
6060 }
6161
--- a/src/artifact/artifact-info.cpp
+++ b/src/artifact/artifact-info.cpp
@@ -28,9 +28,9 @@ RandomArtActType activation_index(const ObjectType *o_ptr)
2828 return act_idx.value();
2929 }
3030
31- const auto fixed_art_id = enum2i(o_ptr->fixed_artifact_idx);
32- if (o_ptr->is_fixed_artifact() && a_info[fixed_art_id].flags.has(TR_ACTIVATE)) {
33- return a_info[fixed_art_id].act_idx;
31+ const auto &fixed_artifact = a_info.at(o_ptr->fixed_artifact_idx);
32+ if (o_ptr->is_fixed_artifact() && fixed_artifact.flags.has(TR_ACTIVATE)) {
33+ return fixed_artifact.act_idx;
3434 }
3535
3636 if (o_ptr->is_ego() && e_info[o_ptr->ego_idx].flags.has(TR_ACTIVATE)) {
--- a/src/artifact/fixed-art-generator.cpp
+++ b/src/artifact/fixed-art-generator.cpp
@@ -133,7 +133,7 @@ static void invest_special_artifact_abilities(PlayerType *player_ptr, ObjectType
133133 * @param a_ptr 固定アーティファクト情報への参照ポインタ
134134 * @param q_ptr オブジェクト情報への参照ポインタ
135135 */
136-static void fixed_artifact_random_abilities(PlayerType *player_ptr, artifact_type *a_ptr, ObjectType *o_ptr)
136+static void fixed_artifact_random_abilities(PlayerType *player_ptr, const ArtifactType &a_ref, ObjectType *o_ptr)
137137 {
138138 auto give_power = false;
139139 auto give_resistance = false;
@@ -145,15 +145,15 @@ static void fixed_artifact_random_abilities(PlayerType *player_ptr, artifact_typ
145145
146146 invest_special_artifact_abilities(player_ptr, o_ptr);
147147
148- if (a_ptr->gen_flags.has(ItemGenerationTraitType::XTRA_POWER)) {
148+ if (a_ref.gen_flags.has(ItemGenerationTraitType::XTRA_POWER)) {
149149 give_power = true;
150150 }
151151
152- if (a_ptr->gen_flags.has(ItemGenerationTraitType::XTRA_H_RES)) {
152+ if (a_ref.gen_flags.has(ItemGenerationTraitType::XTRA_H_RES)) {
153153 give_resistance = true;
154154 }
155155
156- if (a_ptr->gen_flags.has(ItemGenerationTraitType::XTRA_RES_OR_POWER)) {
156+ if (a_ref.gen_flags.has(ItemGenerationTraitType::XTRA_RES_OR_POWER)) {
157157 if (one_in_(2)) {
158158 give_resistance = true;
159159 } else {
@@ -169,7 +169,7 @@ static void fixed_artifact_random_abilities(PlayerType *player_ptr, artifact_typ
169169 one_high_resistance(o_ptr);
170170 }
171171
172- if (a_ptr->gen_flags.has(ItemGenerationTraitType::XTRA_DICE)) {
172+ if (a_ref.gen_flags.has(ItemGenerationTraitType::XTRA_DICE)) {
173173 do {
174174 o_ptr->dd++;
175175 } while (one_in_(o_ptr->dd));
@@ -186,33 +186,33 @@ static void fixed_artifact_random_abilities(PlayerType *player_ptr, artifact_typ
186186 * @param a_ptr 固定アーティファクト情報への参照ポインタ
187187 * @param q_ptr オブジェクト情報への参照ポインタ
188188 */
189-static void invest_curse_to_fixed_artifact(artifact_type *a_ptr, ObjectType *o_ptr)
189+static void invest_curse_to_fixed_artifact(const ArtifactType &a_ref, ObjectType *o_ptr)
190190 {
191- if (!a_ptr->cost) {
191+ if (!a_ref.cost) {
192192 set_bits(o_ptr->ident, IDENT_BROKEN);
193193 }
194194
195- if (a_ptr->gen_flags.has(ItemGenerationTraitType::CURSED)) {
195+ if (a_ref.gen_flags.has(ItemGenerationTraitType::CURSED)) {
196196 o_ptr->curse_flags.set(CurseTraitType::CURSED);
197197 }
198198
199- if (a_ptr->gen_flags.has(ItemGenerationTraitType::HEAVY_CURSE)) {
199+ if (a_ref.gen_flags.has(ItemGenerationTraitType::HEAVY_CURSE)) {
200200 o_ptr->curse_flags.set(CurseTraitType::HEAVY_CURSE);
201201 }
202202
203- if (a_ptr->gen_flags.has(ItemGenerationTraitType::PERMA_CURSE)) {
203+ if (a_ref.gen_flags.has(ItemGenerationTraitType::PERMA_CURSE)) {
204204 o_ptr->curse_flags.set(CurseTraitType::PERMA_CURSE);
205205 }
206206
207- if (a_ptr->gen_flags.has(ItemGenerationTraitType::RANDOM_CURSE0)) {
207+ if (a_ref.gen_flags.has(ItemGenerationTraitType::RANDOM_CURSE0)) {
208208 o_ptr->curse_flags.set(get_curse(0, o_ptr));
209209 }
210210
211- if (a_ptr->gen_flags.has(ItemGenerationTraitType::RANDOM_CURSE1)) {
211+ if (a_ref.gen_flags.has(ItemGenerationTraitType::RANDOM_CURSE1)) {
212212 o_ptr->curse_flags.set(get_curse(1, o_ptr));
213213 }
214214
215- if (a_ptr->gen_flags.has(ItemGenerationTraitType::RANDOM_CURSE2)) {
215+ if (a_ref.gen_flags.has(ItemGenerationTraitType::RANDOM_CURSE2)) {
216216 o_ptr->curse_flags.set(get_curse(2, o_ptr));
217217 }
218218 }
@@ -223,23 +223,21 @@ static void invest_curse_to_fixed_artifact(artifact_type *a_ptr, ObjectType *o_p
223223 * @param o_ptr 生成に割り当てたいオブジェクトの構造体参照ポインタ
224224 * @return 適用したアーティファクト情報への参照ポインタ
225225 */
226-artifact_type *apply_artifact(PlayerType *player_ptr, ObjectType *o_ptr)
226+void apply_artifact(PlayerType *player_ptr, ObjectType *o_ptr)
227227 {
228- auto a_ptr = &a_info[enum2i(o_ptr->fixed_artifact_idx)];
229- o_ptr->pval = a_ptr->pval;
230- o_ptr->ac = a_ptr->ac;
231- o_ptr->dd = a_ptr->dd;
232- o_ptr->ds = a_ptr->ds;
233- o_ptr->to_a = a_ptr->to_a;
234- o_ptr->to_h = a_ptr->to_h;
235- o_ptr->to_d = a_ptr->to_d;
236- o_ptr->weight = a_ptr->weight;
237- o_ptr->activation_id = a_ptr->act_idx;
238-
239- invest_curse_to_fixed_artifact(a_ptr, o_ptr);
240- fixed_artifact_random_abilities(player_ptr, a_ptr, o_ptr);
241-
242- return a_ptr;
228+ auto &a_ref = a_info.at(o_ptr->fixed_artifact_idx);
229+ o_ptr->pval = a_ref.pval;
230+ o_ptr->ac = a_ref.ac;
231+ o_ptr->dd = a_ref.dd;
232+ o_ptr->ds = a_ref.ds;
233+ o_ptr->to_a = a_ref.to_a;
234+ o_ptr->to_h = a_ref.to_h;
235+ o_ptr->to_d = a_ref.to_d;
236+ o_ptr->weight = a_ref.weight;
237+ o_ptr->activation_id = a_ref.act_idx;
238+
239+ invest_curse_to_fixed_artifact(a_ref, o_ptr);
240+ fixed_artifact_random_abilities(player_ptr, a_ref, o_ptr);
243241 }
244242
245243 /*!
@@ -256,7 +254,7 @@ artifact_type *apply_artifact(PlayerType *player_ptr, ObjectType *o_ptr)
256254 */
257255 bool create_named_art(PlayerType *player_ptr, FixedArtifactId a_idx, POSITION y, POSITION x)
258256 {
259- auto a_ptr = &a_info[enum2i(a_idx)];
257+ auto a_ptr = &a_info.at(a_idx);
260258 if (a_ptr->name.empty()) {
261259 return false;
262260 }
@@ -271,7 +269,7 @@ bool create_named_art(PlayerType *player_ptr, FixedArtifactId a_idx, POSITION y,
271269 q_ptr->prep(i);
272270 q_ptr->fixed_artifact_idx = a_idx;
273271
274- (void)apply_artifact(player_ptr, q_ptr);
272+ apply_artifact(player_ptr, q_ptr);
275273
276274 return drop_near(player_ptr, q_ptr, -1, y, x) > 0;
277275 }
@@ -298,7 +296,7 @@ bool make_artifact(PlayerType *player_ptr, ObjectType *o_ptr)
298296 return false;
299297 }
300298
301- for (const auto &a_ref : a_info) {
299+ for (const auto &[a_idx, a_ref] : a_info) {
302300 if (a_ref.name.empty()) {
303301 continue;
304302 }
@@ -334,7 +332,7 @@ bool make_artifact(PlayerType *player_ptr, ObjectType *o_ptr)
334332 continue;
335333 }
336334
337- o_ptr->fixed_artifact_idx = a_ref.idx;
335+ o_ptr->fixed_artifact_idx = a_idx;
338336 return true;
339337 }
340338
@@ -369,7 +367,7 @@ bool make_artifact_special(PlayerType *player_ptr, ObjectType *o_ptr)
369367 }
370368
371369 /*! @note 全固定アーティファクト中からIDの若い順に生成対象とその確率を走査する / Check the artifact list (just the "specials") */
372- for (const auto &a_ref : a_info) {
370+ for (const auto &[a_idx, a_ref] : a_info) {
373371 /*! @note アーティファクト名が空の不正なデータは除外する / Skip "empty" artifacts */
374372 if (a_ref.name.empty()) {
375373 continue;
@@ -386,8 +384,7 @@ bool make_artifact_special(PlayerType *player_ptr, ObjectType *o_ptr)
386384 continue;
387385 }
388386
389- /*! @note アーティファクト生成階が現在に対して足りない場合は高確率で1/(不足階層*2)を満たさないと生成リストに加えられない /
390- * XXX XXX Enforce minimum "depth" (loosely) */
387+ /*! @note アーティファクト生成階が現在に対して足りない場合は高確率で1/(不足階層*2)を満たさないと生成リストに加えられない */
391388 if (a_ref.level > floor_ptr->object_level) {
392389 /* @note / Acquire the "out-of-depth factor". Roll for out-of-depth creation. */
393390 int d = (a_ref.level - floor_ptr->object_level) * 2;
@@ -401,9 +398,10 @@ bool make_artifact_special(PlayerType *player_ptr, ObjectType *o_ptr)
401398 continue;
402399 }
403400
404- /*! @note INSTA_ART型固定アーティファクトのベースアイテムもチェック対象とする。ベースアイテムの生成階層が足りない場合1/(不足階層*5)
405- * を満たさないと除外される。 / Find the base object. XXX XXX Enforce minimum "object" level (loosely). Acquire the "out-of-depth factor". Roll for
406- * out-of-depth creation. */
401+ /*!
402+ * @note INSTA_ART型固定アーティファクトのベースアイテムもチェック対象とする。
403+ * ベースアイテムの生成階層が足りない場合1/(不足階層*5)を満たさないと除外される。
404+ */
407405 k_idx = lookup_kind(a_ref.tval, a_ref.sval);
408406 if (k_info[k_idx].level > floor_ptr->object_level) {
409407 int d = (k_info[k_idx].level - floor_ptr->object_level) * 5;
@@ -416,7 +414,7 @@ bool make_artifact_special(PlayerType *player_ptr, ObjectType *o_ptr)
416414 * Assign the template. Mega-Hack -- mark the item as an artifact. Hack: Some artifacts get random extra powers. Success. */
417415 o_ptr->prep(k_idx);
418416
419- o_ptr->fixed_artifact_idx = a_ref.idx;
417+ o_ptr->fixed_artifact_idx = a_idx;
420418 return true;
421419 }
422420
--- a/src/artifact/fixed-art-generator.h
+++ b/src/artifact/fixed-art-generator.h
@@ -7,10 +7,10 @@
77 #include "system/angband.h"
88
99 enum class FixedArtifactId : short;
10-struct artifact_type;
10+class ArtifactType;
1111 class ObjectType;
1212 class PlayerType;
1313 bool create_named_art(PlayerType *player_ptr, FixedArtifactId a_idx, POSITION y, POSITION x);
1414 bool make_artifact(PlayerType *player_ptr, ObjectType *o_ptr);
15-artifact_type *apply_artifact(PlayerType *player_ptr, ObjectType *o_ptr);
15+void apply_artifact(PlayerType *player_ptr, ObjectType *o_ptr);
1616 bool make_artifact_special(PlayerType *player_ptr, ObjectType *o_ptr);
--- a/src/birth/game-play-initializer.cpp
+++ b/src/birth/game-play-initializer.cpp
@@ -77,7 +77,7 @@ void player_wipe_without_name(PlayerType *player_ptr)
7777 (&player_ptr->inventory_list[i])->wipe();
7878 }
7979
80- for (auto &a_ref : a_info) {
80+ for (auto &[a_idx, a_ref] : a_info) {
8181 a_ref.is_generated = false;
8282 }
8383
--- a/src/combat/shoot.cpp
+++ b/src/combat/shoot.cpp
@@ -955,8 +955,7 @@ void exe_fire(PlayerType *player_ptr, INVENTORY_IDX item, ObjectType *j_ptr, SPE
955955 if (!o_idx) {
956956 msg_format(_("%sはどこかへ行った。", "The %s went somewhere."), o_name);
957957 if (q_ptr->is_fixed_artifact()) {
958- const auto fixed_artifact_idx = enum2i(j_ptr->fixed_artifact_idx);
959- a_info[fixed_artifact_idx].is_generated = false;
958+ a_info.at(j_ptr->fixed_artifact_idx).is_generated = false;
960959 }
961960 return;
962961 }
--- a/src/dungeon/quest.cpp
+++ b/src/dungeon/quest.cpp
@@ -411,7 +411,7 @@ void leave_quest_check(PlayerType *player_ptr)
411411 quest_list[QuestId::TOWER1].complev = player_ptr->lev;
412412 break;
413413 case QuestKindType::FIND_ARTIFACT:
414- a_info[enum2i(q_ptr->reward_artifact_idx)].gen_flags.reset(ItemGenerationTraitType::QUESTITEM);
414+ a_info.at(q_ptr->reward_artifact_idx).gen_flags.reset(ItemGenerationTraitType::QUESTITEM);
415415 break;
416416 case QuestKindType::RANDOM:
417417 r_info[q_ptr->r_idx].flags1 &= ~(RF1_QUESTOR);
--- a/src/flavor/flavor-util.cpp
+++ b/src/flavor/flavor-util.cpp
@@ -197,8 +197,8 @@ char *get_ability_abbreviation(char *short_flavor, ObjectType *o_ptr, bool kanji
197197 flgs.reset(k_ptr->flags);
198198
199199 if (o_ptr->is_fixed_artifact()) {
200- auto *a_ptr = &a_info[enum2i(o_ptr->fixed_artifact_idx)];
201- flgs.reset(a_ptr->flags);
200+ const auto &a_ref = a_info.at(o_ptr->fixed_artifact_idx);
201+ flgs.reset(a_ref.flags);
202202 }
203203
204204 if (o_ptr->is_ego()) {
--- a/src/flavor/named-item-describer.cpp
+++ b/src/flavor/named-item-describer.cpp
@@ -59,8 +59,9 @@ static void set_base_name(flavor_type *flavor_ptr)
5959 return;
6060 }
6161
62- const auto fixed_art_id = enum2i(flavor_ptr->o_ptr->fixed_artifact_idx);
63- flavor_ptr->basenm = (flavor_ptr->known && flavor_ptr->o_ptr->is_fixed_artifact() && !any_bits(flavor_ptr->mode, OD_BASE_NAME)) ? a_info[fixed_art_id].name.c_str() : flavor_ptr->kindname;
62+ const auto fixed_art_id = flavor_ptr->o_ptr->fixed_artifact_idx;
63+ const auto is_known_artifact = flavor_ptr->known && flavor_ptr->o_ptr->is_fixed_artifact() && none_bits(flavor_ptr->mode, OD_BASE_NAME);
64+ flavor_ptr->basenm = is_known_artifact ? a_info.at(fixed_art_id).name.c_str() : flavor_ptr->kindname;
6465 }
6566
6667 #ifdef JP
@@ -122,10 +123,10 @@ static void describe_artifact_ja(flavor_type *flavor_ptr)
122123 }
123124
124125 if (flavor_ptr->o_ptr->is_fixed_artifact() && flavor_ptr->tr_flags.has_not(TR_FULL_NAME)) {
125- auto *a_ptr = &a_info[enum2i(flavor_ptr->o_ptr->fixed_artifact_idx)];
126+ const auto &a_ref = a_info.at(flavor_ptr->o_ptr->fixed_artifact_idx);
126127 /* '『' から始まらない伝説のアイテムの名前は最初に付加する */
127- if (a_ptr->name.find("『", 0, 2) != 0) {
128- flavor_ptr->t = object_desc_str(flavor_ptr->t, a_ptr->name.c_str());
128+ if (a_ref.name.find("『", 0, 2) != 0) {
129+ flavor_ptr->t = object_desc_str(flavor_ptr->t, a_ref.name.c_str());
129130 }
130131
131132 return;
@@ -215,9 +216,9 @@ static void describe_artifact_body_ja(flavor_type *flavor_ptr)
215216 }
216217
217218 if (flavor_ptr->o_ptr->is_fixed_artifact()) {
218- auto *a_ptr = &a_info[enum2i(flavor_ptr->o_ptr->fixed_artifact_idx)];
219- if (a_ptr->name.find("『", 0, 2) == 0) {
220- flavor_ptr->t = object_desc_str(flavor_ptr->t, a_ptr->name.c_str());
219+ const auto &a_ref = a_info.at(flavor_ptr->o_ptr->fixed_artifact_idx);
220+ if (a_ref.name.find("『", 0, 2) == 0) {
221+ flavor_ptr->t = object_desc_str(flavor_ptr->t, a_ref.name.c_str());
221222 }
222223
223224 return;
@@ -250,10 +251,10 @@ static void describe_vowel(flavor_type *flavor_ptr)
250251 }
251252
252253 /*!
253- * @brief 0個、1個、2個以上の時に個数を書き分ける処理 / Process to write the number when there are 0, 1, or 2 or more.
254- * @param flavor_ptr アイテム表記への参照ポインタ / Reference pointer to item's flavor
255- * @return 1個ならFALSE、0または2個以上ならTRUE / If the number of items is 1, then FALE is returned, and if 0 or 2 or more, then TRUE is returned
256- * @details 1個なら後続処理実行 / If the number of items is 1, then the continuous process will be run.
254+ * @brief Process to write the number of items when there are 0, 1, or 2 or more.
255+ * @param flavor_ptr Reference pointer to item's flavor
256+ * @return If the number of items is 1, then FALE is returned, and if 0 or 2 or more, then TRUE is returned
257+ * @details If the number of items is 1, then the continuous process will be run.
257258 */
258259 static bool describe_prefix_en(flavor_type *flavor_ptr)
259260 {
@@ -283,7 +284,9 @@ static void describe_artifact_prefix_en(flavor_type *flavor_ptr)
283284 }
284285
285286 const auto corpse_r_idx = i2enum<MonsterRaceId>(flavor_ptr->o_ptr->pval);
286- if ((flavor_ptr->known && flavor_ptr->o_ptr->is_artifact()) || ((flavor_ptr->o_ptr->tval == ItemKindType::CORPSE) && r_info[corpse_r_idx].kind_flags.has(MonsterKindType::UNIQUE))) {
287+ auto is_unique_corpse = flavor_ptr->o_ptr->tval == ItemKindType::CORPSE;
288+ is_unique_corpse &= r_info[corpse_r_idx].kind_flags.has(MonsterKindType::UNIQUE);
289+ if ((flavor_ptr->known && flavor_ptr->o_ptr->is_artifact()) || is_unique_corpse) {
287290 flavor_ptr->t = object_desc_str(flavor_ptr->t, "The ");
288291 return;
289292 }
@@ -320,9 +323,9 @@ static void describe_artifact_body_en(flavor_type *flavor_ptr)
320323 }
321324
322325 if (flavor_ptr->o_ptr->is_fixed_artifact()) {
323- auto *a_ptr = &a_info[enum2i(flavor_ptr->o_ptr->fixed_artifact_idx)];
326+ const auto &a_ref = a_info.at(flavor_ptr->o_ptr->fixed_artifact_idx);
324327 flavor_ptr->t = object_desc_chr(flavor_ptr->t, ' ');
325- flavor_ptr->t = object_desc_str(flavor_ptr->t, a_ptr->name.c_str());
328+ flavor_ptr->t = object_desc_str(flavor_ptr->t, a_ref.name.c_str());
326329 return;
327330 }
328331
--- a/src/floor/fixed-map-generator.cpp
+++ b/src/floor/fixed-map-generator.cpp
@@ -81,9 +81,9 @@ static void generate_artifact(PlayerType *player_ptr, qtwg_type *qtwg_ptr, const
8181 return;
8282 }
8383
84- const auto int_artifact_index = enum2i(artifact_index);
85- if (!a_info[int_artifact_index].is_generated && create_named_art(player_ptr, artifact_index, *qtwg_ptr->y, *qtwg_ptr->x)) {
86- a_info[int_artifact_index].is_generated = true;
84+ auto &fixed_artifact = a_info.at(artifact_index);
85+ if (!fixed_artifact.is_generated && create_named_art(player_ptr, artifact_index, *qtwg_ptr->y, *qtwg_ptr->x)) {
86+ fixed_artifact.is_generated = true;
8787 return;
8888 }
8989
@@ -208,9 +208,6 @@ static bool parse_qtw_QQ(quest_type *q_ptr, char **zz, int num)
208208 return true;
209209 }
210210
211- monster_race *r_ptr;
212- artifact_type *a_ptr;
213-
214211 if (num < 9) {
215212 return true;
216213 }
@@ -221,20 +218,30 @@ static bool parse_qtw_QQ(quest_type *q_ptr, char **zz, int num)
221218 q_ptr->max_num = (MONSTER_NUMBER)atoi(zz[5]);
222219 q_ptr->level = (DEPTH)atoi(zz[6]);
223220 q_ptr->r_idx = i2enum<MonsterRaceId>(atoi(zz[7]));
224- q_ptr->reward_artifact_idx = i2enum<FixedArtifactId>(atoi(zz[8]));
221+ const auto a_idx = i2enum<FixedArtifactId>(atoi(zz[8]));
222+ q_ptr->reward_artifact_idx = a_idx;
225223 q_ptr->dungeon = (DUNGEON_IDX)atoi(zz[9]);
226224
227225 if (num > 10) {
228226 q_ptr->flags = atoi(zz[10]);
229227 }
230228
231- r_ptr = &r_info[q_ptr->r_idx];
232- if (r_ptr->kind_flags.has(MonsterKindType::UNIQUE)) {
233- r_ptr->flags1 |= RF1_QUESTOR;
229+ auto &r_ref = r_info[q_ptr->r_idx];
230+ if (r_ref.kind_flags.has(MonsterKindType::UNIQUE)) {
231+ r_ref.flags1 |= RF1_QUESTOR;
232+ }
233+
234+ if (a_idx == FixedArtifactId::NONE) {
235+ return true;
236+ }
237+
238+ // @note 半分デッドコード。reward_artifact_idx が定義されているクエストが1つもない.
239+ if (const auto it = a_info.find(a_idx); it == a_info.end()) {
240+ return true;
234241 }
235242
236- a_ptr = &a_info[enum2i(q_ptr->reward_artifact_idx)];
237- a_ptr->gen_flags.set(ItemGenerationTraitType::QUESTITEM);
243+ auto &a_ref = a_info.at(q_ptr->reward_artifact_idx);
244+ a_ref.gen_flags.set(ItemGenerationTraitType::QUESTITEM);
238245 return true;
239246 }
240247
@@ -259,7 +266,7 @@ static bool parse_qtw_QR(quest_type *q_ptr, char **zz, int num)
259266 continue;
260267 }
261268
262- if (a_info[enum2i(a_idx)].is_generated) {
269+ if (a_info.at(a_idx).is_generated) {
263270 continue;
264271 }
265272
@@ -271,7 +278,7 @@ static bool parse_qtw_QR(quest_type *q_ptr, char **zz, int num)
271278
272279 if (reward_idx != FixedArtifactId::NONE) {
273280 q_ptr->reward_artifact_idx = reward_idx;
274- a_info[enum2i(reward_idx)].gen_flags.set(ItemGenerationTraitType::QUESTITEM);
281+ a_info.at(reward_idx).gen_flags.set(ItemGenerationTraitType::QUESTITEM);
275282 } else {
276283 q_ptr->type = QuestKindType::KILL_ALL;
277284 }
--- a/src/floor/floor-changer.cpp
+++ b/src/floor/floor-changer.cpp
@@ -195,7 +195,7 @@ static void update_unique_artifact(floor_type *floor_ptr, int16_t cur_floor_id)
195195 }
196196
197197 if (o_ptr->is_fixed_artifact()) {
198- a_info[enum2i(o_ptr->fixed_artifact_idx)].floor_id = cur_floor_id;
198+ a_info.at(o_ptr->fixed_artifact_idx).floor_id = cur_floor_id;
199199 }
200200 }
201201 }
@@ -296,9 +296,9 @@ static void new_floor_allocation(PlayerType *player_ptr, saved_floor_type *sf_pt
296296 continue;
297297 }
298298
299- const auto fixed_artifact_idx = enum2i(o_ptr->fixed_artifact_idx);
300- if (a_info[fixed_artifact_idx].floor_id == new_floor_id) {
301- a_info[fixed_artifact_idx].is_generated = true;
299+ auto &fixed_artifact = a_info.at(o_ptr->fixed_artifact_idx);
300+ if (fixed_artifact.floor_id == new_floor_id) {
301+ fixed_artifact.is_generated = true;
302302 } else {
303303 delete_object_idx(player_ptr, i);
304304 }
--- a/src/floor/floor-leaver.cpp
+++ b/src/floor/floor-leaver.cpp
@@ -296,7 +296,7 @@ static void preserve_info(PlayerType *player_ptr)
296296 }
297297
298298 if (o_ptr->is_fixed_artifact()) {
299- a_info[enum2i(o_ptr->fixed_artifact_idx)].floor_id = 0;
299+ a_info.at(o_ptr->fixed_artifact_idx).floor_id = 0;
300300 }
301301 }
302302 }
--- a/src/floor/floor-object.cpp
+++ b/src/floor/floor-object.cpp
@@ -485,8 +485,7 @@ OBJECT_IDX drop_near(PlayerType *player_ptr, ObjectType *j_ptr, PERCENTAGE chanc
485485
486486 if (preserve_mode) {
487487 if (j_ptr->is_fixed_artifact() && !j_ptr->is_known()) {
488- const auto fixed_artifact_idx = enum2i(j_ptr->fixed_artifact_idx);
489- a_info[fixed_artifact_idx].is_generated = false;
488+ a_info.at(j_ptr->fixed_artifact_idx).is_generated = false;
490489 }
491490 }
492491
@@ -539,8 +538,7 @@ OBJECT_IDX drop_near(PlayerType *player_ptr, ObjectType *j_ptr, PERCENTAGE chanc
539538 }
540539
541540 if (j_ptr->is_fixed_artifact()) {
542- const auto fixed_artifact_idx = enum2i(j_ptr->fixed_artifact_idx);
543- a_info[fixed_artifact_idx].is_generated = false;
541+ a_info.at(j_ptr->fixed_artifact_idx).is_generated = false;
544542 }
545543
546544 return 0;
--- a/src/floor/floor-streams.cpp
+++ b/src/floor/floor-streams.cpp
@@ -353,7 +353,7 @@ void build_streamer(PlayerType *player_ptr, FEAT_IDX feat, int chance)
353353
354354 /* Hack -- Preserve unknown artifacts */
355355 if (o_ptr->is_fixed_artifact()) {
356- a_info[enum2i(o_ptr->fixed_artifact_idx)].is_generated = false;
356+ a_info.at(o_ptr->fixed_artifact_idx).is_generated = false;
357357
358358 if (cheat_peek) {
359359 GAME_TEXT o_name[MAX_NLEN];
--- a/src/floor/floor-util.cpp
+++ b/src/floor/floor-util.cpp
@@ -131,7 +131,7 @@ void wipe_o_list(floor_type *floor_ptr)
131131
132132 if (!w_ptr->character_dungeon || preserve_mode) {
133133 if (o_ptr->is_fixed_artifact() && !o_ptr->is_known()) {
134- a_info[enum2i(o_ptr->fixed_artifact_idx)].is_generated = false;
134+ a_info.at(o_ptr->fixed_artifact_idx).is_generated = false;
135135 }
136136 }
137137
--- a/src/grid/object-placer.cpp
+++ b/src/grid/object-placer.cpp
@@ -90,8 +90,7 @@ void place_object(PlayerType *player_ptr, POSITION y, POSITION x, BIT_FLAGS mode
9090 OBJECT_IDX o_idx = o_pop(floor_ptr);
9191 if (o_idx == 0) {
9292 if (q_ptr->is_fixed_artifact()) {
93- const auto fixed_artifact_idx = enum2i(q_ptr->fixed_artifact_idx);
94- a_info[fixed_artifact_idx].is_generated = false;
93+ a_info.at(q_ptr->fixed_artifact_idx).is_generated = false;
9594 }
9695
9796 return;
--- a/src/info-reader/artifact-reader.cpp
+++ b/src/info-reader/artifact-reader.cpp
@@ -1,4 +1,5 @@
11 #include "info-reader/artifact-reader.h"
2+#include "artifact/fixed-art-types.h"
23 #include "artifact/random-art-effects.h"
34 #include "info-reader/info-reader-util.h"
45 #include "info-reader/kind-info-tokens-table.h"
@@ -18,7 +19,7 @@
1819 * @param what 参照元の文字列ポインタ
1920 * @return 見つかったらtrue
2021 */
21-static bool grab_one_artifact_flag(artifact_type *a_ptr, std::string_view what)
22+static bool grab_one_artifact_flag(ArtifactType *a_ptr, std::string_view what)
2223 {
2324 if (TrFlags::grab_one_flag(a_ptr->flags, k_info_flags, what)) {
2425 return true;
@@ -41,45 +42,49 @@ static bool grab_one_artifact_flag(artifact_type *a_ptr, std::string_view what)
4142 */
4243 errr parse_a_info(std::string_view buf, angband_header *)
4344 {
44- static artifact_type *a_ptr = nullptr;
4545 const auto &tokens = str_split(buf, ':', false, 10);
46-
4746 if (tokens[0] == "N") {
4847 // N:index:name_ja
4948 if (tokens.size() < 3 || tokens[1].size() == 0) {
5049 return PARSE_ERROR_GENERIC;
5150 }
5251
53- auto i = std::stoi(tokens[1]);
54- if (i < error_idx) {
52+ const auto int_idx = std::stoi(tokens[1]);
53+ const auto a_idx = i2enum<FixedArtifactId>(int_idx);
54+ if (int_idx < error_idx) {
5555 return PARSE_ERROR_NON_SEQUENTIAL_RECORDS;
5656 }
57- if (i >= static_cast<int>(a_info.size())) {
58- a_info.resize(i + 1);
59- }
60-
61- error_idx = i;
62- a_ptr = &a_info[i];
63- a_ptr->idx = i2enum<FixedArtifactId>(i);
64- a_ptr->flags.set(TR_IGNORE_ACID);
65- a_ptr->flags.set(TR_IGNORE_ELEC);
66- a_ptr->flags.set(TR_IGNORE_FIRE);
67- a_ptr->flags.set(TR_IGNORE_COLD);
6857
58+ error_idx = int_idx;
59+ ArtifactType artifact;
60+ artifact.flags.set(TR_IGNORE_ACID);
61+ artifact.flags.set(TR_IGNORE_ELEC);
62+ artifact.flags.set(TR_IGNORE_FIRE);
63+ artifact.flags.set(TR_IGNORE_COLD);
6964 #ifdef JP
70- a_ptr->name = tokens[2];
65+ artifact.name = tokens[2];
7166 #endif
72- } else if (!a_ptr) {
73- return PARSE_ERROR_MISSING_RECORD_HEADER;
74- } else if (tokens[0] == "E") {
67+ a_info.emplace(a_idx, artifact);
68+ return PARSE_ERROR_NONE;
69+ }
70+
71+ if (tokens[0] == "E") {
7572 // E:name_en
76-#ifndef JP
73+#ifdef JP
74+ return PARSE_ERROR_NONE;
75+#else
7776 if (tokens[1].size() == 0) {
7877 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
7978 }
80- a_ptr->name = tokens[1];
79+
80+ const auto it = a_info.rbegin();
81+ auto &a_ref = it->second;
82+ a_ref.name = tokens[1];
83+ return PARSE_ERROR_NONE;
8184 #endif
82- } else if (tokens[0] == "D") {
85+ }
86+
87+ if (tokens[0] == "D") {
8388 // D:JapaneseText
8489 // D:$EnglishText
8590 if (tokens.size() < 2 || tokens[1].size() == 0) {
@@ -89,33 +94,52 @@ errr parse_a_info(std::string_view buf, angband_header *)
8994 if (tokens[1][0] == '$') {
9095 return PARSE_ERROR_NONE;
9196 }
92- a_ptr->text.append(buf.substr(2));
97+
98+ const auto it = a_info.rbegin();
99+ auto &a_ref = it->second;
100+ a_ref.text.append(buf.substr(2));
93101 #else
94102 if (tokens[1][0] != '$') {
95103 return PARSE_ERROR_NONE;
96104 }
97- append_english_text(a_ptr->text, buf.substr(3));
105+
106+ const auto it = a_info.rbegin();
107+ auto &a_ref = it->second;
108+ append_english_text(a_ref.text, buf.substr(3));
98109 #endif
99- } else if (tokens[0] == "I") {
110+ return PARSE_ERROR_NONE;
111+ }
112+
113+ if (tokens[0] == "I") {
100114 // I:tval:sval:pval
101115 if (tokens.size() < 4) {
102116 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
103117 }
104118
105- info_set_value(a_ptr->tval, tokens[1]);
106- info_set_value(a_ptr->sval, tokens[2]);
107- info_set_value(a_ptr->pval, tokens[3]);
108- } else if (tokens[0] == "W") {
119+ const auto it = a_info.rbegin();
120+ auto &a_ref = it->second;
121+ info_set_value(a_ref.tval, tokens[1]);
122+ info_set_value(a_ref.sval, tokens[2]);
123+ info_set_value(a_ref.pval, tokens[3]);
124+ return PARSE_ERROR_NONE;
125+ }
126+
127+ if (tokens[0] == "W") {
109128 // W:level:ratiry:weight:cost
110129 if (tokens.size() < 5) {
111130 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
112131 }
113132
114- info_set_value(a_ptr->level, tokens[1]);
115- info_set_value(a_ptr->rarity, tokens[2]);
116- info_set_value(a_ptr->weight, tokens[3]);
117- info_set_value(a_ptr->cost, tokens[4]);
118- } else if (tokens[0] == "P") {
133+ const auto it = a_info.rbegin();
134+ auto &a_ref = it->second;
135+ info_set_value(a_ref.level, tokens[1]);
136+ info_set_value(a_ref.rarity, tokens[2]);
137+ info_set_value(a_ref.weight, tokens[3]);
138+ info_set_value(a_ref.cost, tokens[4]);
139+ return PARSE_ERROR_NONE;
140+ }
141+
142+ if (tokens[0] == "P") {
119143 // P:ac:dd:ds:to_h:to_d:to_a
120144 if (tokens.size() < 6) {
121145 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
@@ -126,24 +150,35 @@ errr parse_a_info(std::string_view buf, angband_header *)
126150 return PARSE_ERROR_NON_SEQUENTIAL_RECORDS;
127151 }
128152
129- info_set_value(a_ptr->ac, tokens[1]);
130- info_set_value(a_ptr->dd, dice[0]);
131- info_set_value(a_ptr->ds, dice[1]);
132- info_set_value(a_ptr->to_h, tokens[3]);
133- info_set_value(a_ptr->to_d, tokens[4]);
134- info_set_value(a_ptr->to_a, tokens[5]);
135- } else if (tokens[0] == "U") {
153+ const auto it = a_info.rbegin();
154+ auto &a_ref = it->second;
155+ info_set_value(a_ref.ac, tokens[1]);
156+ info_set_value(a_ref.dd, dice[0]);
157+ info_set_value(a_ref.ds, dice[1]);
158+ info_set_value(a_ref.to_h, tokens[3]);
159+ info_set_value(a_ref.to_d, tokens[4]);
160+ info_set_value(a_ref.to_a, tokens[5]);
161+ return PARSE_ERROR_NONE;
162+ }
163+
164+ if (tokens[0] == "U") {
136165 // U:activation_flag
137166 if (tokens.size() < 2 || tokens[1].size() == 0) {
138167 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
139168 }
169+
140170 auto n = grab_one_activation_flag(tokens[1].c_str());
141171 if (n <= RandomArtActType::NONE) {
142172 return PARSE_ERROR_INVALID_FLAG;
143173 }
144174
145- a_ptr->act_idx = n;
146- } else if (tokens[0] == "F") {
175+ const auto it = a_info.rbegin();
176+ auto &a_ref = it->second;
177+ a_ref.act_idx = n;
178+ return PARSE_ERROR_NONE;
179+ }
180+
181+ if (tokens[0] == "F") {
147182 // F:flags
148183 if (tokens.size() < 2 || tokens[1].size() == 0) {
149184 return PARSE_ERROR_TOO_FEW_ARGUMENTS;
@@ -154,13 +189,16 @@ errr parse_a_info(std::string_view buf, angband_header *)
154189 if (f.size() == 0) {
155190 continue;
156191 }
192+
193+ const auto it = a_info.rbegin();
194+ auto *a_ptr = &it->second;
157195 if (!grab_one_artifact_flag(a_ptr, f)) {
158196 return PARSE_ERROR_INVALID_FLAG;
159197 }
160198 }
161- } else {
162- return PARSE_ERROR_UNDEFINED_DIRECTIVE;
199+
200+ return PARSE_ERROR_NONE;
163201 }
164202
165- return PARSE_ERROR_NONE;
203+ return PARSE_ERROR_UNDEFINED_DIRECTIVE;
166204 }
--- a/src/info-reader/general-parser.cpp
+++ b/src/info-reader/general-parser.cpp
@@ -146,9 +146,9 @@ parse_error_type parse_line_feature(floor_type *floor_ptr, char *buf)
146146 const auto &quest_list = QuestList::get_instance();
147147 const auto a_idx = quest_list[floor_ptr->quest_number].reward_artifact_idx;
148148 if (a_idx != FixedArtifactId::NONE) {
149- const auto *a_ptr = &a_info[enum2i(a_idx)];
150- if (a_ptr->gen_flags.has_not(ItemGenerationTraitType::INSTA_ART)) {
151- letter[index].object = lookup_kind(a_ptr->tval, a_ptr->sval);
149+ const auto &a_ref = a_info.at(a_idx);
150+ if (a_ref.gen_flags.has_not(ItemGenerationTraitType::INSTA_ART)) {
151+ letter[index].object = lookup_kind(a_ref.tval, a_ref.sval);
152152 }
153153 }
154154 }
--- a/src/knowledge/knowledge-items.cpp
+++ b/src/knowledge/knowledge-items.cpp
@@ -31,7 +31,6 @@
3131 #include "util/sort.h"
3232 #include "view/display-messages.h"
3333 #include "world/world.h"
34-
3534 #include <numeric>
3635
3736 /*!
@@ -48,11 +47,12 @@ void do_cmd_knowledge_artifacts(PlayerType *player_ptr)
4847 }
4948
5049 std::map<FixedArtifactId, bool> okay;
51- for (auto i = 0U; i < a_info.size(); i++) {
50+ auto num_artifacts = enum2i(a_info.rbegin()->first);
51+ for (auto i = 0; i <= num_artifacts; i++) {
5252 okay.emplace(i2enum<FixedArtifactId>(i), false);
5353 }
5454
55- for (const auto &a_ref : a_info) {
55+ for (const auto &[a_idx, a_ref] : a_info) {
5656 if (a_ref.name.empty()) {
5757 continue;
5858 }
@@ -60,7 +60,7 @@ void do_cmd_knowledge_artifacts(PlayerType *player_ptr)
6060 continue;
6161 }
6262
63- okay[a_ref.idx] = true;
63+ okay[a_idx] = true;
6464 }
6565
6666 for (POSITION y = 0; y < player_ptr->current_floor_ptr->height; y++) {
@@ -97,19 +97,19 @@ void do_cmd_knowledge_artifacts(PlayerType *player_ptr)
9797 }
9898
9999 std::vector<FixedArtifactId> whats;
100- for (const auto &a_ref : a_info) {
101- if (okay[a_ref.idx]) {
102- whats.push_back(a_ref.idx);
100+ for (const auto &[a_idx, a_ref] : a_info) {
101+ if (okay[a_idx]) {
102+ whats.push_back(a_idx);
103103 }
104104 }
105105
106106 uint16_t why = 3;
107107 ang_sort(player_ptr, whats.data(), &why, whats.size(), ang_sort_art_comp, ang_sort_art_swap);
108108 for (auto a_idx : whats) {
109- auto *a_ptr = &a_info[enum2i(a_idx)];
109+ const auto &a_ref = a_info.at(a_idx);
110110 GAME_TEXT base_name[MAX_NLEN];
111111 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
112- const auto z = lookup_kind(a_ptr->tval, a_ptr->sval);
112+ const auto z = lookup_kind(a_ref.tval, a_ref.sval);
113113 if (z != 0) {
114114 ObjectType forge;
115115 ObjectType *q_ptr;
--- a/src/knowledge/knowledge-quests.cpp
+++ b/src/knowledge/knowledge-quests.cpp
@@ -101,10 +101,10 @@ static void do_cmd_knowledge_quests_current(PlayerType *player_ptr, FILE *fff)
101101
102102 case QuestKindType::FIND_ARTIFACT:
103103 if (q_ref.reward_artifact_idx != FixedArtifactId::NONE) {
104- auto *a_ptr = &a_info[enum2i(q_ref.reward_artifact_idx)];
104+ const auto &a_ref = a_info.at(q_ref.reward_artifact_idx);
105105 ObjectType forge;
106106 auto *o_ptr = &forge;
107- KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
107+ KIND_OBJECT_IDX k_idx = lookup_kind(a_ref.tval, a_ref.sval);
108108 o_ptr->prep(k_idx);
109109 o_ptr->fixed_artifact_idx = q_ref.reward_artifact_idx;
110110 o_ptr->ident = IDENT_STORE;
--- a/src/load/item/item-loader-base.cpp
+++ b/src/load/item/item-loader-base.cpp
@@ -1,9 +1,11 @@
11 #include "load/item/item-loader-base.h"
2+#include "artifact/fixed-art-types.h"
23 #include "load/angband-version-comparer.h"
34 #include "load/load-util.h"
45 #include "object/object-kind.h"
56 #include "system/artifact-type-definition.h"
67 #include "util/bit-flags-calculator.h"
8+#include "util/enum-converter.h"
79
810 /*!
911 * @brief アイテムオブジェクトの鑑定情報をロードする.
@@ -27,16 +29,18 @@ void ItemLoaderBase::load_item(void)
2729 */
2830 void ItemLoaderBase::load_artifact(void)
2931 {
32+ ArtifactType dummy;
3033 auto loading_max_a_idx = rd_u16b();
31- artifact_type dummy;
3234 for (auto i = 0U; i < loading_max_a_idx; i++) {
33- auto *a_ptr = i < a_info.size() ? &a_info[i] : &dummy;
34- a_ptr->is_generated = rd_bool();
35+ const auto a_idx = i2enum<FixedArtifactId>(i);
36+ const auto it = a_info.find(a_idx);
37+ auto &artifact = it != a_info.end() ? it->second : dummy;
38+ artifact.is_generated = rd_bool();
3539 if (h_older_than(1, 5, 0, 0)) {
36- a_ptr->floor_id = 0;
40+ artifact.floor_id = 0;
3741 strip_bytes(3);
3842 } else {
39- a_ptr->floor_id = rd_s16b();
43+ artifact.floor_id = rd_s16b();
4044 }
4145 }
4246
--- a/src/load/old/load-v1-5-0.cpp
+++ b/src/load/old/load-v1-5-0.cpp
@@ -132,19 +132,19 @@ void rd_item_old(ObjectType *o_ptr)
132132 o_ptr->curse_flags.set(CurseTraitType::PERMA_CURSE);
133133 }
134134 if (o_ptr->is_fixed_artifact()) {
135- auto *a_ptr = &a_info[enum2i(o_ptr->fixed_artifact_idx)];
136- if (a_ptr->gen_flags.has(ItemGenerationTraitType::HEAVY_CURSE)) {
135+ const auto &a_ref = a_info.at(o_ptr->fixed_artifact_idx);
136+ if (a_ref.gen_flags.has(ItemGenerationTraitType::HEAVY_CURSE)) {
137137 o_ptr->curse_flags.set(CurseTraitType::HEAVY_CURSE);
138138 }
139- if (a_ptr->gen_flags.has(ItemGenerationTraitType::PERMA_CURSE)) {
139+ if (a_ref.gen_flags.has(ItemGenerationTraitType::PERMA_CURSE)) {
140140 o_ptr->curse_flags.set(CurseTraitType::PERMA_CURSE);
141141 }
142142 } else if (o_ptr->is_ego()) {
143- auto *e_ptr = &e_info[o_ptr->ego_idx];
144- if (e_ptr->gen_flags.has(ItemGenerationTraitType::HEAVY_CURSE)) {
143+ const auto &e_ref = e_info[o_ptr->ego_idx];
144+ if (e_ref.gen_flags.has(ItemGenerationTraitType::HEAVY_CURSE)) {
145145 o_ptr->curse_flags.set(CurseTraitType::HEAVY_CURSE);
146146 }
147- if (e_ptr->gen_flags.has(ItemGenerationTraitType::PERMA_CURSE)) {
147+ if (e_ref.gen_flags.has(ItemGenerationTraitType::PERMA_CURSE)) {
148148 o_ptr->curse_flags.set(CurseTraitType::PERMA_CURSE);
149149 }
150150 }
@@ -339,15 +339,15 @@ void rd_item_old(ObjectType *o_ptr)
339339 }
340340
341341 if (o_ptr->is_fixed_artifact()) {
342- const auto *a_ptr = &a_info[enum2i(o_ptr->fixed_artifact_idx)];
343- if (a_ptr->name.empty()) {
342+ const auto &a_ref = a_info.at(o_ptr->fixed_artifact_idx);
343+ if (a_ref.name.empty()) {
344344 o_ptr->fixed_artifact_idx = FixedArtifactId::NONE;
345345 }
346346 }
347347
348348 if (o_ptr->is_ego()) {
349- auto *e_ptr = &e_info[o_ptr->ego_idx];
350- if (e_ptr->name.empty()) {
349+ const auto &e_ref = e_info[o_ptr->ego_idx];
350+ if (e_ref.name.empty()) {
351351 o_ptr->ego_idx = EgoType::NONE;
352352 }
353353 }
--- a/src/load/quest-loader.cpp
+++ b/src/load/quest-loader.cpp
@@ -72,7 +72,7 @@ static void load_quest_details(PlayerType *player_ptr, quest_type *q_ptr, const
7272 }
7373 q_ptr->reward_artifact_idx = i2enum<FixedArtifactId>(rd_s16b());
7474 if (q_ptr->reward_artifact_idx != FixedArtifactId::NONE) {
75- a_info[enum2i(q_ptr->reward_artifact_idx)].gen_flags.set(ItemGenerationTraitType::QUESTITEM);
75+ a_info.at(q_ptr->reward_artifact_idx).gen_flags.set(ItemGenerationTraitType::QUESTITEM);
7676 }
7777
7878 q_ptr->flags = rd_byte();
--- a/src/monster-floor/monster-death.cpp
+++ b/src/monster-floor/monster-death.cpp
@@ -179,20 +179,20 @@ static FixedArtifactId drop_artifact_index(PlayerType *player_ptr, monster_death
179179 */
180180 bool drop_single_artifact(PlayerType *player_ptr, monster_death_type *md_ptr, FixedArtifactId a_idx)
181181 {
182- auto *a_ptr = &a_info[enum2i(a_idx)];
183- if (a_ptr->is_generated) {
182+ auto &a_ref = a_info.at(a_idx);
183+ if (a_ref.is_generated) {
184184 return false;
185185 }
186186
187187 if (create_named_art(player_ptr, a_idx, md_ptr->md_y, md_ptr->md_x)) {
188- a_ptr->is_generated = true;
188+ a_ref.is_generated = true;
189189
190190 if (w_ptr->character_dungeon) {
191- a_ptr->floor_id = player_ptr->floor_id;
191+ a_ref.floor_id = player_ptr->floor_id;
192192 }
193193
194194 if (!preserve_mode) {
195- a_ptr->is_generated = true;
195+ a_ref.is_generated = true;
196196 }
197197
198198 return true;
@@ -208,17 +208,17 @@ static KIND_OBJECT_IDX drop_dungeon_final_artifact(PlayerType *player_ptr, monst
208208 }
209209
210210 a_idx = d_info[player_ptr->dungeon_idx].final_artifact;
211- auto *a_ptr = &a_info[enum2i(a_idx)];
212- if (a_ptr->is_generated) {
211+ auto &a_ref = a_info.at(a_idx);
212+ if (a_ref.is_generated) {
213213 return k_idx;
214214 }
215215 if (create_named_art(player_ptr, a_idx, md_ptr->md_y, md_ptr->md_x)) {
216- a_ptr->is_generated = true;
216+ a_ref.is_generated = true;
217217 if (w_ptr->character_dungeon) {
218- a_ptr->floor_id = player_ptr->floor_id;
218+ a_ref.floor_id = player_ptr->floor_id;
219219 }
220220 } else if (!preserve_mode) {
221- a_ptr->is_generated = true;
221+ a_ref.is_generated = true;
222222 }
223223
224224 return d_info[player_ptr->dungeon_idx].final_object ? k_idx : 0;
--- a/src/monster-floor/special-death-switcher.cpp
+++ b/src/monster-floor/special-death-switcher.cpp
@@ -169,7 +169,7 @@ static void on_dead_sacred_treasures(PlayerType *player_ptr, monster_death_type
169169 }
170170
171171 FixedArtifactId a_idx = FixedArtifactId::NONE;
172- artifact_type *a_ptr = nullptr;
172+ ArtifactType *a_ptr = nullptr;
173173 do {
174174 switch (randint0(3)) {
175175 case 0:
@@ -183,7 +183,7 @@ static void on_dead_sacred_treasures(PlayerType *player_ptr, monster_death_type
183183 break;
184184 }
185185
186- a_ptr = &a_info[enum2i(a_idx)];
186+ a_ptr = &a_info.at(a_idx);
187187 } while (a_ptr->is_generated);
188188
189189 if (create_named_art(player_ptr, a_idx, md_ptr->md_y, md_ptr->md_x)) {
--- a/src/object-enchant/item-magic-applier.cpp
+++ b/src/object-enchant/item-magic-applier.cpp
@@ -181,10 +181,11 @@ bool ItemMagicApplier::set_fixed_artifact_generation_info()
181181 return false;
182182 }
183183
184- auto *a_ptr = apply_artifact(this->player_ptr, this->o_ptr);
185- a_ptr->is_generated = true;
184+ apply_artifact(this->player_ptr, this->o_ptr);
185+ auto &a_ref = a_info.at(this->o_ptr->fixed_artifact_idx);
186+ a_ref.is_generated = true;
186187 if (w_ptr->character_dungeon) {
187- a_ptr->floor_id = this->player_ptr->floor_id;
188+ a_ref.floor_id = this->player_ptr->floor_id;
188189 }
189190
190191 return true;
--- a/src/object-hook/hook-quest.cpp
+++ b/src/object-hook/hook-quest.cpp
@@ -58,10 +58,10 @@ bool object_is_quest_target(QuestId quest_idx, ObjectType *o_ptr)
5858 return false;
5959 }
6060
61- auto *a_ptr = &a_info[enum2i(a_idx)];
62- if (a_ptr->gen_flags.has(ItemGenerationTraitType::INSTA_ART)) {
61+ const auto &a_ref = a_info.at(a_idx);
62+ if (a_ref.gen_flags.has(ItemGenerationTraitType::INSTA_ART)) {
6363 return false;
6464 }
6565
66- return (o_ptr->tval == a_ptr->tval) && (o_ptr->sval == a_ptr->sval);
66+ return (o_ptr->tval == a_ref.tval) && (o_ptr->sval == a_ref.sval);
6767 }
--- a/src/object/object-flags.cpp
+++ b/src/object/object-flags.cpp
@@ -55,7 +55,7 @@ TrFlags object_flags(const ObjectType *o_ptr)
5555 auto flgs = k_ptr->flags;
5656
5757 if (o_ptr->is_fixed_artifact()) {
58- flgs = a_info[enum2i(o_ptr->fixed_artifact_idx)].flags;
58+ flgs = a_info.at(o_ptr->fixed_artifact_idx).flags;
5959 }
6060
6161 object_flags_lite(o_ptr, flgs);
@@ -100,7 +100,7 @@ TrFlags object_flags_known(const ObjectType *o_ptr)
100100 object_flags_lite(o_ptr, flgs);
101101 if (spoil || o_ptr->is_fully_known()) {
102102 if (o_ptr->is_fixed_artifact()) {
103- flgs = a_info[enum2i(o_ptr->fixed_artifact_idx)].flags;
103+ flgs = a_info.at(o_ptr->fixed_artifact_idx).flags;
104104 }
105105
106106 /* Random artifact ! */
--- a/src/object/object-value-calc.cpp
+++ b/src/object/object-value-calc.cpp
@@ -31,11 +31,11 @@ PRICE flag_cost(const ObjectType *o_ptr, int plusses)
3131 flgs.reset(k_ptr->flags);
3232
3333 if (o_ptr->is_fixed_artifact()) {
34- auto *a_ptr = &a_info[enum2i(o_ptr->fixed_artifact_idx)];
35- flgs.reset(a_ptr->flags);
34+ const auto &a_ref = a_info.at(o_ptr->fixed_artifact_idx);
35+ flgs.reset(a_ref.flags);
3636 } else if (o_ptr->is_ego()) {
37- auto *e_ptr = &e_info[o_ptr->ego_idx];
38- flgs.reset(e_ptr->flags);
37+ const auto &e_ref = e_info[o_ptr->ego_idx];
38+ flgs.reset(e_ref.flags);
3939 }
4040
4141 /*
--- a/src/object/object-value.cpp
+++ b/src/object/object-value.cpp
@@ -157,21 +157,21 @@ PRICE object_value_real(const ObjectType *o_ptr)
157157 PRICE value = k_info[o_ptr->k_idx].cost;
158158 auto flgs = object_flags(o_ptr);
159159 if (o_ptr->is_fixed_artifact()) {
160- auto *a_ptr = &a_info[enum2i(o_ptr->fixed_artifact_idx)];
161- if (!a_ptr->cost) {
160+ const auto &a_ref = a_info.at(o_ptr->fixed_artifact_idx);
161+ if (!a_ref.cost) {
162162 return 0;
163163 }
164164
165- value = a_ptr->cost;
165+ value = a_ref.cost;
166166 value += flag_cost(o_ptr, o_ptr->pval);
167167 return value;
168168 } else if (o_ptr->is_ego()) {
169- auto *e_ptr = &e_info[o_ptr->ego_idx];
170- if (!e_ptr->cost) {
169+ const auto &e_ref = e_info[o_ptr->ego_idx];
170+ if (!e_ref.cost) {
171171 return 0;
172172 }
173173
174- value += e_ptr->cost;
174+ value += e_ref.cost;
175175 value += flag_cost(o_ptr, o_ptr->pval);
176176 } else {
177177 if (o_ptr->art_flags.any()) {
--- a/src/perception/identification.cpp
+++ b/src/perception/identification.cpp
@@ -43,7 +43,8 @@ bool screen_object(PlayerType *player_ptr, ObjectType *o_ptr, BIT_FLAGS mode)
4343 int trivial_info = 0;
4444 auto flgs = object_flags(o_ptr);
4545
46- shape_buffer(o_ptr->is_fixed_artifact() ? a_info[enum2i(o_ptr->fixed_artifact_idx)].text.c_str() : k_info[o_ptr->k_idx].text.c_str(), 77 - 15, temp, sizeof(temp));
46+ const auto item_text = o_ptr->is_fixed_artifact() ? a_info.at(o_ptr->fixed_artifact_idx).text.c_str() : k_info[o_ptr->k_idx].text.c_str();
47+ shape_buffer(item_text, 77 - 15, temp, sizeof(temp));
4748
4849 int i = 0;
4950 for (int j = 0; temp[j]; j += 1 + strlen(&temp[j])) {
--- a/src/racial/racial-android.cpp
+++ b/src/racial/racial-android.cpp
@@ -83,9 +83,9 @@ void calc_android_exp(PlayerType *player_ptr)
8383 q_ptr->curse_flags.clear();
8484
8585 if (o_ptr->is_fixed_artifact()) {
86- const auto fixed_artifact_idx = enum2i(o_ptr->fixed_artifact_idx);
87- level = (level + std::max(a_info[fixed_artifact_idx].level - 8, 5)) / 2;
88- level += std::min(20, a_info[fixed_artifact_idx].rarity / (a_info[fixed_artifact_idx].gen_flags.has(ItemGenerationTraitType::INSTA_ART) ? 10 : 3));
86+ const auto &fixed_artifact = a_info.at(o_ptr->fixed_artifact_idx);
87+ level = (level + std::max(fixed_artifact.level - 8, 5)) / 2;
88+ level += std::min(20, fixed_artifact.rarity / (fixed_artifact.gen_flags.has(ItemGenerationTraitType::INSTA_ART) ? 10 : 3));
8989 } else if (o_ptr->is_ego()) {
9090 level += std::max(3, (e_info[o_ptr->ego_idx].rating - 5) / 2);
9191 } else if (o_ptr->art_name) {
--- a/src/save/save.cpp
+++ b/src/save/save.cpp
@@ -41,6 +41,7 @@
4141 #include "util/angband-files.h"
4242 #include "view/display-messages.h"
4343 #include "world/world.h"
44+#include <algorithm>
4445
4546 /*!
4647 * @brief セーブデータの書き込み /
@@ -166,12 +167,16 @@ static bool wr_savefile_new(PlayerType *player_ptr, SaveType type)
166167 }
167168 }
168169
169- tmp16u = static_cast<uint16_t>(a_info.size());
170+ auto max_a_num = enum2i(a_info.rbegin()->first);
171+ tmp16u = max_a_num + 1;
170172 wr_u16b(tmp16u);
171- for (int i = 0; i < tmp16u; i++) {
172- auto *a_ptr = &a_info[i];
173- wr_bool(a_ptr->is_generated);
174- wr_s16b(a_ptr->floor_id);
173+ ArtifactType dummy;
174+ for (auto i = 0U; i < tmp16u; i++) {
175+ const auto a_idx = i2enum<FixedArtifactId>(i);
176+ const auto it = a_info.find(a_idx);
177+ const auto &a_ref = it != a_info.end() ? it->second : dummy;
178+ wr_bool(a_ref.is_generated);
179+ wr_s16b(a_ref.floor_id);
175180 }
176181
177182 wr_u32b(w_ptr->sf_play_time);
--- a/src/specific-object/bloody-moon.cpp
+++ b/src/specific-object/bloody-moon.cpp
@@ -18,7 +18,7 @@
1818 */
1919 void get_bloody_moon_flags(ObjectType *o_ptr)
2020 {
21- o_ptr->art_flags = a_info[enum2i(FixedArtifactId::BLOOD)].flags;
21+ o_ptr->art_flags = a_info.at(FixedArtifactId::BLOOD).flags;
2222
2323 int dummy = randint1(2) + randint1(2);
2424 for (int i = 0; i < dummy; i++) {
--- a/src/spell-kind/spells-floor.cpp
+++ b/src/spell-kind/spells-floor.cpp
@@ -345,7 +345,7 @@ bool destroy_area(PlayerType *player_ptr, POSITION y1, POSITION x1, POSITION r,
345345
346346 /* Hack -- Preserve unknown artifacts */
347347 if (o_ptr->is_fixed_artifact() && (!o_ptr->is_known() || in_generate)) {
348- a_info[enum2i(o_ptr->fixed_artifact_idx)].is_generated = false;
348+ a_info.at(o_ptr->fixed_artifact_idx).is_generated = false;
349349
350350 if (in_generate && cheat_peek) {
351351 GAME_TEXT o_name[MAX_NLEN];
--- a/src/spell/spells-object.cpp
+++ b/src/spell/spells-object.cpp
@@ -89,8 +89,8 @@ static const std::vector<amuse_type> amuse_info = {
8989
9090 static std::optional<FixedArtifactId> sweep_amusement_artifact(const bool insta_art, const short k_idx)
9191 {
92- for (const auto &a_ref : a_info) {
93- if (a_ref.idx == FixedArtifactId::NONE) {
92+ for (const auto &[a_idx, a_ref] : a_info) {
93+ if (a_idx == FixedArtifactId::NONE) {
9494 continue;
9595 }
9696
@@ -110,7 +110,7 @@ static std::optional<FixedArtifactId> sweep_amusement_artifact(const bool insta_
110110 continue;
111111 }
112112
113- return a_ref.idx;
113+ return a_idx;
114114 }
115115
116116 return std::nullopt;
--- a/src/store/rumor.cpp
+++ b/src/store/rumor.cpp
@@ -66,11 +66,10 @@ void display_rumor(PlayerType *player_ptr, bool ex)
6666 char fullname[1024] = "";
6767 if (strcmp(zz[0], "ARTIFACT") == 0) {
6868 FixedArtifactId a_idx;
69- artifact_type *a_ptr;
69+ ArtifactType *a_ptr;
7070 while (true) {
71- a_idx = i2enum<FixedArtifactId>(rumor_num(zz[1], static_cast<IDX>(a_info.size())));
72-
73- a_ptr = &a_info[enum2i(a_idx)];
71+ a_idx = i2enum<FixedArtifactId>(rumor_num(zz[1], enum2i(a_info.rbegin()->first)));
72+ a_ptr = &a_info.at(a_idx);
7473 if (!a_ptr->name.empty()) {
7574 break;
7675 }
--- a/src/system/artifact-type-definition.cpp
+++ b/src/system/artifact-type-definition.cpp
@@ -3,4 +3,4 @@
33 /*
44 * The artifact arrays
55 */
6-std::vector<artifact_type> a_info;
6+std::map<FixedArtifactId, ArtifactType> a_info;
--- a/src/system/artifact-type-definition.h
+++ b/src/system/artifact-type-definition.h
@@ -6,22 +6,19 @@
66 #include "object-enchant/trg-types.h"
77 #include "system/object-type-definition.h"
88 #include "util/flag-group.h"
9-
9+#include <map>
1010 #include <string>
11-#include <vector>
1211
1312 /*!
14- * @struct artifact_type
13+ * @class ArtifactType
1514 * @brief 固定アーティファクト情報の構造体 / Artifact structure.
16- * @details
17- * @note
18- * the save-file only writes "is_generated" to the savefile.
19- * "max_num" is always "1" (if that artifact "exists")
15+ * @details is_generated とfloor_id フィールドのみセーブファイルへの保存対象
2016 */
2117 enum class FixedArtifactId : short;
2218 enum class RandomArtActType : short;
23-struct artifact_type {
24- FixedArtifactId idx{};
19+class ArtifactType {
20+public:
21+ ArtifactType() = default;
2522
2623 std::string name; /*!< アーティファクト名 / Name */
2724 std::string text; /*!< アーティファクト解説 / Text */
@@ -45,4 +42,4 @@ struct artifact_type {
4542 RandomArtActType act_idx{}; /*! 発動能力ID / Activative ability index */
4643 };
4744
48-extern std::vector<artifact_type> a_info;
45+extern std::map<FixedArtifactId, ArtifactType> a_info;
--- a/src/util/sort.cpp
+++ b/src/util/sort.cpp
@@ -1,4 +1,5 @@
11 #include "util/sort.h"
2+#include "artifact/fixed-art-types.h"
23 #include "dungeon/quest.h"
34 #include "grid/feature.h"
45 #include "grid/grid.h"
@@ -260,16 +261,17 @@ bool ang_sort_art_comp(PlayerType *player_ptr, vptr u, vptr v, int a, int b)
260261 uint16_t *who = (uint16_t *)(u);
261262 uint16_t *why = (uint16_t *)(v);
262263
263- int w1 = who[a];
264- int w2 = who[b];
264+ const auto w1 = i2enum<FixedArtifactId>(who[a]);
265+ const auto w2 = i2enum<FixedArtifactId>(who[b]);
265266
266- int z1, z2;
267+ int z1;
268+ int z2;
267269
268270 /* Sort by total kills */
269271 if (*why >= 3) {
270272 /* Extract total kills */
271- z1 = enum2i(a_info[w1].tval);
272- z2 = enum2i(a_info[w2].tval);
273+ z1 = enum2i(a_info.at(w1).tval);
274+ z2 = enum2i(a_info.at(w2).tval);
273275
274276 /* Compare total kills */
275277 if (z1 < z2) {
@@ -284,8 +286,8 @@ bool ang_sort_art_comp(PlayerType *player_ptr, vptr u, vptr v, int a, int b)
284286 /* Sort by monster level */
285287 if (*why >= 2) {
286288 /* Extract levels */
287- z1 = a_info[w1].sval;
288- z2 = a_info[w2].sval;
289+ z1 = a_info.at(w1).sval;
290+ z2 = a_info.at(w2).sval;
289291
290292 /* Compare levels */
291293 if (z1 < z2) {
@@ -300,8 +302,8 @@ bool ang_sort_art_comp(PlayerType *player_ptr, vptr u, vptr v, int a, int b)
300302 /* Sort by monster experience */
301303 if (*why >= 1) {
302304 /* Extract experience */
303- z1 = a_info[w1].level;
304- z2 = a_info[w2].level;
305+ z1 = a_info.at(w1).level;
306+ z2 = a_info.at(w2).level;
305307
306308 /* Compare experience */
307309 if (z1 < z2) {
--- a/src/wizard/artifact-analyzer.cpp
+++ b/src/wizard/artifact-analyzer.cpp
@@ -259,26 +259,26 @@ static void analyze_misc_magic(ObjectType *o_ptr, concptr *misc_list)
259259 */
260260 static void analyze_addition(ObjectType *o_ptr, char *addition)
261261 {
262- auto *a_ptr = &a_info[enum2i(o_ptr->fixed_artifact_idx)];
262+ const auto &a_ref = a_info.at(o_ptr->fixed_artifact_idx);
263263 strcpy(addition, "");
264264
265- if (a_ptr->gen_flags.has_all_of({ ItemGenerationTraitType::XTRA_POWER, ItemGenerationTraitType::XTRA_H_RES })) {
265+ if (a_ref.gen_flags.has_all_of({ ItemGenerationTraitType::XTRA_POWER, ItemGenerationTraitType::XTRA_H_RES })) {
266266 strcat(addition, _("能力and耐性", "Ability and Resistance"));
267- } else if (a_ptr->gen_flags.has(ItemGenerationTraitType::XTRA_POWER)) {
267+ } else if (a_ref.gen_flags.has(ItemGenerationTraitType::XTRA_POWER)) {
268268 strcat(addition, _("能力", "Ability"));
269- if (a_ptr->gen_flags.has(ItemGenerationTraitType::XTRA_RES_OR_POWER)) {
269+ if (a_ref.gen_flags.has(ItemGenerationTraitType::XTRA_RES_OR_POWER)) {
270270 strcat(addition, _("(1/2でand耐性)", "(plus Resistance about 1/2)"));
271271 }
272- } else if (a_ptr->gen_flags.has(ItemGenerationTraitType::XTRA_H_RES)) {
272+ } else if (a_ref.gen_flags.has(ItemGenerationTraitType::XTRA_H_RES)) {
273273 strcat(addition, _("耐性", "Resistance"));
274- if (a_ptr->gen_flags.has(ItemGenerationTraitType::XTRA_RES_OR_POWER)) {
274+ if (a_ref.gen_flags.has(ItemGenerationTraitType::XTRA_RES_OR_POWER)) {
275275 strcat(addition, _("(1/2でand能力)", "(plus Ability about 1/2)"));
276276 }
277- } else if (a_ptr->gen_flags.has(ItemGenerationTraitType::XTRA_RES_OR_POWER)) {
277+ } else if (a_ref.gen_flags.has(ItemGenerationTraitType::XTRA_RES_OR_POWER)) {
278278 strcat(addition, _("能力or耐性", "Ability or Resistance"));
279279 }
280280
281- if (a_ptr->gen_flags.has(ItemGenerationTraitType::XTRA_DICE)) {
281+ if (a_ref.gen_flags.has(ItemGenerationTraitType::XTRA_DICE)) {
282282 if (strlen(addition) > 0) {
283283 strcat(addition, _("、", ", "));
284284 }
@@ -295,9 +295,9 @@ static void analyze_addition(ObjectType *o_ptr, char *addition)
295295 */
296296 static void analyze_misc(ObjectType *o_ptr, char *misc_desc)
297297 {
298- auto *a_ptr = &a_info[enum2i(o_ptr->fixed_artifact_idx)];
299- sprintf(misc_desc, _("レベル %d, 希少度 %u, %d.%d kg, $%ld", "Level %d, Rarity %u, %d.%d lbs, %ld Gold"), (int)a_ptr->level, a_ptr->rarity,
300- _(lb_to_kg_integer(a_ptr->weight), a_ptr->weight / 10), _(lb_to_kg_fraction(a_ptr->weight), a_ptr->weight % 10), (long int)a_ptr->cost);
298+ const auto &a_ref = a_info.at(o_ptr->fixed_artifact_idx);
299+ sprintf(misc_desc, _("レベル %d, 希少度 %u, %d.%d kg, $%ld", "Level %d, Rarity %u, %d.%d lbs, %ld Gold"), (int)a_ref.level, a_ref.rarity,
300+ _(lb_to_kg_integer(a_ref.weight), a_ref.weight / 10), _(lb_to_kg_fraction(a_ref.weight), a_ref.weight % 10), (long int)a_ref.cost);
301301 }
302302
303303 /*!
--- a/src/wizard/fixed-artifacts-spoiler.cpp
+++ b/src/wizard/fixed-artifacts-spoiler.cpp
@@ -86,26 +86,26 @@ static void print_header(void)
8686 */
8787 static bool make_fake_artifact(ObjectType *o_ptr, FixedArtifactId fixed_artifact_idx)
8888 {
89- auto *a_ptr = &a_info[enum2i(fixed_artifact_idx)];
90- if (a_ptr->name.empty()) {
89+ auto &a_ref = a_info.at(fixed_artifact_idx);
90+ if (a_ref.name.empty()) {
9191 return false;
9292 }
9393
94- OBJECT_IDX i = lookup_kind(a_ptr->tval, a_ptr->sval);
94+ OBJECT_IDX i = lookup_kind(a_ref.tval, a_ref.sval);
9595 if (!i) {
9696 return false;
9797 }
9898
9999 o_ptr->prep(i);
100100 o_ptr->fixed_artifact_idx = fixed_artifact_idx;
101- o_ptr->pval = a_ptr->pval;
102- o_ptr->ac = a_ptr->ac;
103- o_ptr->dd = a_ptr->dd;
104- o_ptr->ds = a_ptr->ds;
105- o_ptr->to_a = a_ptr->to_a;
106- o_ptr->to_h = a_ptr->to_h;
107- o_ptr->to_d = a_ptr->to_d;
108- o_ptr->weight = a_ptr->weight;
101+ o_ptr->pval = a_ref.pval;
102+ o_ptr->ac = a_ref.ac;
103+ o_ptr->dd = a_ref.dd;
104+ o_ptr->ds = a_ref.ds;
105+ o_ptr->to_a = a_ref.to_a;
106+ o_ptr->to_h = a_ref.to_h;
107+ o_ptr->to_d = a_ref.to_d;
108+ o_ptr->weight = a_ref.weight;
109109 return true;
110110 }
111111
@@ -164,14 +164,14 @@ SpoilerOutputResultType spoil_fixed_artifact(concptr fname)
164164 spoiler_blanklines(1);
165165
166166 for (auto tval : tval_list) {
167- for (const auto &a_ref : a_info) {
167+ for (const auto &[a_idx, a_ref] : a_info) {
168168 if (a_ref.tval != tval) {
169169 continue;
170170 }
171171
172172 ObjectType obj;
173173 obj.wipe();
174- if (!make_fake_artifact(&obj, a_ref.idx)) {
174+ if (!make_fake_artifact(&obj, a_idx)) {
175175 continue;
176176 }
177177
--- a/src/wizard/wizard-item-modifier.cpp
+++ b/src/wizard/wizard-item-modifier.cpp
@@ -99,7 +99,7 @@ T clamp_cast(int val)
9999 static_cast<int>(std::numeric_limits<T>::max())));
100100 }
101101
102-void wiz_restore_aware_flag_of_fixed_arfifact(FixedArtifactId a_idx, bool aware = false);
102+void wiz_restore_aware_flag_of_fixed_arfifact(FixedArtifactId reset_artifact_idx, bool aware = false);
103103 void wiz_modify_item_activation(PlayerType *player_ptr);
104104 void wiz_identify_full_inventory(PlayerType *player_ptr);
105105
@@ -173,14 +173,15 @@ void wizard_item_modifier(PlayerType *player_ptr)
173173 /*!
174174 * @brief 固定アーティファクトの出現フラグをリセットする
175175 * @param a_idx 指定したアーティファクトID
176- * @details 外からはenum class を受け取るが、この関数内では数値の直指定処理なので即数値型にキャストする.
176+ * @details 外からはenum class を受け取るが、この関数内では数値の直指定処理なので数値型にキャストする.
177177 */
178-void wiz_restore_aware_flag_of_fixed_arfifact(FixedArtifactId a_idx, bool aware)
178+void wiz_restore_aware_flag_of_fixed_arfifact(FixedArtifactId reset_artifact_idx, bool aware)
179179 {
180- auto int_a_idx = enum2i(a_idx);
180+ auto max_a_idx = enum2i(a_info.rbegin()->first);
181+ auto int_a_idx = enum2i(reset_artifact_idx);
181182 if (int_a_idx <= 0) {
182183 char tmp[80] = "";
183- sprintf(tmp, "Artifact ID (1-%d): ", static_cast<int>(a_info.size()) - 1);
184+ sprintf(tmp, "Artifact ID (1-%d): ", max_a_idx);
184185 char tmp_val[10] = "";
185186 if (!get_string(tmp, tmp_val, 3)) {
186187 return;
@@ -189,13 +190,12 @@ void wiz_restore_aware_flag_of_fixed_arfifact(FixedArtifactId a_idx, bool aware)
189190 int_a_idx = static_cast<short>(atoi(tmp_val));
190191 }
191192
192- if (int_a_idx <= 0 || int_a_idx >= static_cast<short>(a_info.size())) {
193- msg_format(_("番号は1から%dの間で指定して下さい。", "ID must be between 1 to %d."), a_info.size() - 1);
193+ if ((int_a_idx <= 0) || (int_a_idx > static_cast<short>(max_a_idx))) {
194+ msg_format(_("番号は1から%dの間で指定して下さい。", "ID must be between 1 to %d."), max_a_idx);
194195 return;
195196 }
196197
197- auto *a_ptr = &a_info[int_a_idx];
198- a_ptr->is_generated = aware;
198+ a_info.at(i2enum<FixedArtifactId>(int_a_idx)).is_generated = aware;
199199 msg_print(aware ? "Modified." : "Restored.");
200200 }
201201
@@ -416,9 +416,8 @@ static void wiz_statistics(PlayerType *player_ptr, ObjectType *o_ptr)
416416 concptr p = "Enter number of items to roll: ";
417417 char tmp_val[80];
418418
419- const auto o_fixed_artifact_idx = enum2i(o_ptr->fixed_artifact_idx);
420419 if (o_ptr->is_fixed_artifact()) {
421- a_info[o_fixed_artifact_idx].is_generated = false;
420+ a_info.at(o_ptr->fixed_artifact_idx).is_generated = false;
422421 }
423422
424423 uint32_t i, matches, better, worse, other, correct;
@@ -471,9 +470,8 @@ static void wiz_statistics(PlayerType *player_ptr, ObjectType *o_ptr)
471470 auto *q_ptr = &forge;
472471 q_ptr->wipe();
473472 make_object(player_ptr, q_ptr, mode);
474- const auto q_fixed_artifact_idx = enum2i(q_ptr->fixed_artifact_idx);
475473 if (q_ptr->is_fixed_artifact()) {
476- a_info[q_fixed_artifact_idx].is_generated = false;
474+ a_info.at(q_ptr->fixed_artifact_idx).is_generated = false;
477475 }
478476
479477 if ((o_ptr->tval != q_ptr->tval) || (o_ptr->sval != q_ptr->sval)) {
@@ -481,7 +479,8 @@ static void wiz_statistics(PlayerType *player_ptr, ObjectType *o_ptr)
481479 }
482480
483481 correct++;
484- if ((q_ptr->pval == o_ptr->pval) && (q_ptr->to_a == o_ptr->to_a) && (q_ptr->to_h == o_ptr->to_h) && (q_ptr->to_d == o_ptr->to_d) && (q_fixed_artifact_idx == o_fixed_artifact_idx)) {
482+ const auto is_same_fixed_artifact_idx = q_ptr->fixed_artifact_idx == o_ptr->fixed_artifact_idx;
483+ if ((q_ptr->pval == o_ptr->pval) && (q_ptr->to_a == o_ptr->to_a) && (q_ptr->to_h == o_ptr->to_h) && (q_ptr->to_d == o_ptr->to_d) && is_same_fixed_artifact_idx) {
485484 matches++;
486485 } else if ((q_ptr->pval >= o_ptr->pval) && (q_ptr->to_a >= o_ptr->to_a) && (q_ptr->to_h >= o_ptr->to_h) && (q_ptr->to_d >= o_ptr->to_d)) {
487486 better++;
@@ -497,7 +496,7 @@ static void wiz_statistics(PlayerType *player_ptr, ObjectType *o_ptr)
497496 }
498497
499498 if (o_ptr->is_fixed_artifact()) {
500- a_info[o_fixed_artifact_idx].is_generated = true;
499+ a_info.at(o_ptr->fixed_artifact_idx).is_generated = true;
501500 }
502501 }
503502
@@ -521,10 +520,9 @@ static void wiz_reroll_item(PlayerType *player_ptr, ObjectType *o_ptr)
521520 bool changed = false;
522521 while (true) {
523522 wiz_display_item(player_ptr, q_ptr);
524- const auto int_fixed_artifact_idx = enum2i(q_ptr->fixed_artifact_idx);
525523 if (!get_com("[a]ccept, [w]orthless, [c]ursed, [n]ormal, [g]ood, [e]xcellent, [s]pecial? ", &ch, false)) {
526524 if (q_ptr->is_fixed_artifact()) {
527- a_info[int_fixed_artifact_idx].is_generated = false;
525+ a_info.at(q_ptr->fixed_artifact_idx).is_generated = false;
528526 q_ptr->fixed_artifact_idx = FixedArtifactId::NONE;
529527 }
530528
@@ -538,7 +536,7 @@ static void wiz_reroll_item(PlayerType *player_ptr, ObjectType *o_ptr)
538536 }
539537
540538 if (q_ptr->is_fixed_artifact()) {
541- a_info[int_fixed_artifact_idx].is_generated = false;
539+ a_info.at(q_ptr->fixed_artifact_idx).is_generated = false;
542540 q_ptr->fixed_artifact_idx = FixedArtifactId::NONE;
543541 }
544542
@@ -952,8 +950,8 @@ WishResultType do_cmd_wishing(PlayerType *player_ptr, int prob, bool allow_art,
952950
953951 int len;
954952 int mlen = 0;
955- for (const auto &a_ref : a_info) {
956- if (a_ref.idx == FixedArtifactId::NONE || a_ref.name.empty()) {
953+ for (const auto &[a_idx, a_ref] : a_info) {
954+ if (a_idx == FixedArtifactId::NONE || a_ref.name.empty()) {
957955 continue;
958956 }
959957
@@ -963,7 +961,7 @@ WishResultType do_cmd_wishing(PlayerType *player_ptr, int prob, bool allow_art,
963961 }
964962
965963 o_ptr->prep(k_idx);
966- o_ptr->fixed_artifact_idx = a_ref.idx;
964+ o_ptr->fixed_artifact_idx = a_idx;
967965
968966 describe_flavor(player_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY | OD_STORE));
969967 #ifndef JP
@@ -1005,7 +1003,7 @@ WishResultType do_cmd_wishing(PlayerType *player_ptr, int prob, bool allow_art,
10051003 #endif
10061004
10071005 if (cheat_xtra) {
1008- msg_format("Matching artifact No.%d %s(%s)", a_ref.idx, a_desc, _(&o_name[2], o_name));
1006+ msg_format("Matching artifact No.%d %s(%s)", a_idx, a_desc, _(&o_name[2], o_name));
10091007 }
10101008
10111009 std::vector<const char *> l = { a_str, a_ref.name.c_str(), _(&o_name[2], o_name) };
@@ -1013,7 +1011,7 @@ WishResultType do_cmd_wishing(PlayerType *player_ptr, int prob, bool allow_art,
10131011 if (!strcmp(str, l.at(c))) {
10141012 len = strlen(l.at(c));
10151013 if (len > mlen) {
1016- a_ids.push_back(a_ref.idx);
1014+ a_ids.push_back(a_idx);
10171015 mlen = len;
10181016 }
10191017 }
@@ -1028,11 +1026,11 @@ WishResultType do_cmd_wishing(PlayerType *player_ptr, int prob, bool allow_art,
10281026
10291027 if (a_ids.size() == 1) {
10301028 const auto a_idx = a_ids.back();
1031- const auto int_a_idx = enum2i(a_idx);
1032- if (must || (ok_art && !a_info[int_a_idx].is_generated)) {
1029+ auto &a_ref = a_info.at(a_idx);
1030+ if (must || (ok_art && !a_ref.is_generated)) {
10331031 create_named_art(player_ptr, a_idx, player_ptr->y, player_ptr->x);
10341032 if (!w_ptr->wizard) {
1035- a_info[int_a_idx].is_generated = true;
1033+ a_ref.is_generated = true;
10361034 }
10371035 } else {
10381036 wishing_puff_of_smoke();
@@ -1050,25 +1048,23 @@ WishResultType do_cmd_wishing(PlayerType *player_ptr, int prob, bool allow_art,
10501048 KIND_OBJECT_IDX k_idx = k_ids.back();
10511049 auto *k_ptr = &k_info[k_idx];
10521050
1053- artifact_type *a_ptr;
10541051 FixedArtifactId a_idx = FixedArtifactId::NONE;
10551052 if (k_ptr->gen_flags.has(ItemGenerationTraitType::INSTA_ART)) {
1056- for (const auto &a_ref : a_info) {
1057- if (a_ref.idx == FixedArtifactId::NONE || a_ref.tval != k_ptr->tval || a_ref.sval != k_ptr->sval) {
1053+ for (const auto &[a_idx_loop, a_ref_loop] : a_info) {
1054+ if (a_idx_loop == FixedArtifactId::NONE || a_ref_loop.tval != k_ptr->tval || a_ref_loop.sval != k_ptr->sval) {
10581055 continue;
10591056 }
1060- a_idx = a_ref.idx;
1057+ a_idx = a_idx_loop;
10611058 break;
10621059 }
10631060 }
10641061
10651062 if (a_idx != FixedArtifactId::NONE) {
1066- const auto int_a_idx = enum2i(a_idx);
1067- a_ptr = &a_info[int_a_idx];
1068- if (must || (ok_art && !a_ptr->is_generated)) {
1063+ auto &a_ref = a_info.at(a_idx);
1064+ if (must || (ok_art && !a_ref.is_generated)) {
10691065 create_named_art(player_ptr, a_idx, player_ptr->y, player_ptr->x);
10701066 if (!w_ptr->wizard) {
1071- a_info[int_a_idx].is_generated = true;
1067+ a_ref.is_generated = true;
10721068 }
10731069 } else {
10741070 wishing_puff_of_smoke();
--- a/src/wizard/wizard-special-process.cpp
+++ b/src/wizard/wizard-special-process.cpp
@@ -236,12 +236,12 @@ void wiz_create_item(PlayerType *player_ptr)
236236 }
237237
238238 if (k_info[k_idx].gen_flags.has(ItemGenerationTraitType::INSTA_ART)) {
239- for (const auto &a_ref : a_info) {
240- if ((a_ref.idx == FixedArtifactId::NONE) || (a_ref.tval != k_info[k_idx].tval) || (a_ref.sval != k_info[k_idx].sval)) {
239+ for (const auto &[a_idx, a_ref] : a_info) {
240+ if ((a_idx == FixedArtifactId::NONE) || (a_ref.tval != k_info[k_idx].tval) || (a_ref.sval != k_info[k_idx].sval)) {
241241 continue;
242242 }
243243
244- (void)create_named_art(player_ptr, a_ref.idx, player_ptr->y, player_ptr->x);
244+ (void)create_named_art(player_ptr, a_idx, player_ptr->y, player_ptr->x);
245245 msg_print("Allocated(INSTA_ART).");
246246 return;
247247 }
@@ -264,7 +264,7 @@ void wiz_create_item(PlayerType *player_ptr)
264264 */
265265 static std::string wiz_make_named_artifact_desc(PlayerType *player_ptr, FixedArtifactId a_idx)
266266 {
267- const auto &a_ref = a_info[enum2i(a_idx)];
267+ const auto &a_ref = a_info.at(a_idx);
268268 ObjectType obj;
269269 obj.prep(lookup_kind(a_ref.tval, a_ref.sval));
270270 obj.fixed_artifact_idx = a_idx;
@@ -343,9 +343,9 @@ static std::vector<FixedArtifactId> wiz_collect_group_a_idx(const grouper &group
343343 const auto &[tval_list, name] = group_artifact;
344344 std::vector<FixedArtifactId> a_idx_list;
345345 for (auto tval : tval_list) {
346- for (const auto &a_ref : a_info) {
346+ for (const auto &[a_idx, a_ref] : a_info) {
347347 if (a_ref.tval == tval) {
348- a_idx_list.push_back(a_ref.idx);
348+ a_idx_list.push_back(a_idx);
349349 }
350350 }
351351 }
@@ -358,7 +358,6 @@ static std::vector<FixedArtifactId> wiz_collect_group_a_idx(const grouper &group
358358 void wiz_create_named_art(PlayerType *player_ptr)
359359 {
360360 screen_save();
361-
362361 for (auto i = 0U; i < group_artifact_list.size(); ++i) {
363362 const auto &[tval_lit, name] = group_artifact_list[i];
364363 std::stringstream ss;
@@ -368,7 +367,6 @@ void wiz_create_named_art(PlayerType *player_ptr)
368367 }
369368
370369 std::optional<FixedArtifactId> create_a_idx;
371-
372370 while (!create_a_idx.has_value()) {
373371 char cmd = ESCAPE;
374372 get_com("Kind of artifact: ", &cmd, false);
@@ -385,8 +383,23 @@ void wiz_create_named_art(PlayerType *player_ptr)
385383 }
386384
387385 screen_load();
386+ const auto a_idx = create_a_idx.value();
387+ const auto it = a_info.find(a_idx);
388+ if (it == a_info.end()) {
389+ msg_print("The specified artifact is obsoleted for now.");
390+ return;
391+ }
392+
393+ auto &a_ref = it->second;
394+ if (a_ref.is_generated) {
395+ msg_print("It's already allocated.");
396+ return;
397+ }
398+
399+ if (create_named_art(player_ptr, a_idx, player_ptr->y, player_ptr->x)) {
400+ a_ref.is_generated = true;
401+ }
388402
389- create_named_art(player_ptr, create_a_idx.value(), player_ptr->y, player_ptr->x);
390403 msg_print("Allocated.");
391404 }
392405
Show on old repository browser