From: Hourier <66951241+Hourier@users.noreply.github.com> Date: Sun, 25 Dec 2022 03:01:56 +0000 (+0900) Subject: [Refactor] #2651 get_random_line() の引数からchar *を削除し、返り値をstd::optional に変えた --- diff --git a/src/artifact/random-art-characteristics.cpp b/src/artifact/random-art-characteristics.cpp index 16a3759a0..f4d4b27cd 100644 --- a/src/artifact/random-art-characteristics.cpp +++ b/src/artifact/random-art-characteristics.cpp @@ -153,14 +153,16 @@ std::string get_random_name(const ItemEntity &item, bool armour, int power) } auto filename = get_random_art_filename(armour, power); - char random_artifact_name[80]{}; - (void)get_random_line(filename.data(), item.artifact_bias, random_artifact_name); + auto random_artifact_name = get_random_line(filename.data(), item.artifact_bias); #ifdef JP - if (random_artifact_name[0] == 0) { - return get_table_name(); + if (random_artifact_name.has_value()) { + return random_artifact_name.value(); } + + return get_table_name(); +#else + return random_artifact_name.value(); #endif - return random_artifact_name; } /*対邪平均ダメージの計算処理*/ diff --git a/src/flavor/object-flavor.cpp b/src/flavor/object-flavor.cpp index 01fd6580b..c57917a03 100644 --- a/src/flavor/object-flavor.cpp +++ b/src/flavor/object-flavor.cpp @@ -91,52 +91,43 @@ static bool object_easy_know(int i) } /*! - * @brief 各種語彙からランダムな名前を作成する / Create a name from random parts. + * @brief 各種語彙からランダムな名前を作成する * @return std::string 作成した名前 * @details 日本語の場合 aname_j.txt 英語の場合確率に応じて - * syllables 配列と elvish.txt を組み合わせる。\n + * syllables 配列と elvish.txt を組み合わせる */ std::string get_table_name_aux() { - std::string name; + std::stringstream ss; #ifdef JP - char syllable[80]; - get_random_line("aname_j.txt", 1, syllable); - name = syllable; - get_random_line("aname_j.txt", 2, syllable); - name.append(syllable); - return name; + ss << get_random_line("aname_j.txt", 1).value(); + ss << get_random_line("aname_j.txt", 2).value(); + return ss.str(); #else -#define MAX_SYLLABLES 164 /* Used with scrolls (see below) */ - - static concptr syllables[MAX_SYLLABLES] = { "a", "ab", "ag", "aks", "ala", "an", "ankh", "app", "arg", "arze", "ash", "aus", "ban", "bar", "bat", "bek", + static std::vector syllables = { + "a", "ab", "ag", "aks", "ala", "an", "ankh", "app", "arg", "arze", "ash", "aus", "ban", "bar", "bat", "bek", "bie", "bin", "bit", "bjor", "blu", "bot", "bu", "byt", "comp", "con", "cos", "cre", "dalf", "dan", "den", "der", "doe", "dok", "eep", "el", "eng", "er", "ere", "erk", "esh", "evs", "fa", "fid", "flit", "for", "fri", "fu", "gan", "gar", "glen", "gop", "gre", "ha", "he", "hyd", "i", "ing", "ion", "ip", "ish", "it", "ite", "iv", "jo", "kho", "kli", "klis", "la", "lech", "man", "mar", "me", "mi", "mic", "mik", "mon", "mung", "mur", "nag", "nej", "nelg", "nep", "ner", "nes", "nis", "nih", "nin", "o", "od", "ood", "org", "orn", "ox", "oxy", "pay", "pet", "ple", "plu", "po", "pot", "prok", "re", "rea", "rhov", "ri", "ro", "rog", "rok", "rol", "sa", "san", "sat", "see", "sef", "seh", "shu", "ski", "sna", "sne", "snik", "sno", "so", "sol", "sri", "sta", "sun", "ta", "tab", "tem", "ther", "ti", "tox", "trol", "tue", "turs", "u", "ulk", "um", "un", "uni", "ur", "val", "viv", "vly", "vom", "wah", - "wed", "werg", "wex", "whon", "wun", "x", "yerg", "yp", "zun", "tri", "blaa", "jah", "bul", "on", "foo", "ju", "xuxu" }; + "wed", "werg", "wex", "whon", "wun", "x", "yerg", "yp", "zun", "tri", "blaa", "jah", "bul", "on", "foo", "ju", "xuxu" + }; int testcounter = randint1(3) + 1; if (randint1(3) == 2) { while (testcounter--) { - name.append(syllables[randint0(MAX_SYLLABLES)]); + ss << syllables[randint0(syllables.size())]; } } else { - char syllable[80]; testcounter = randint1(2) + 1; while (testcounter--) { -<<<<<<< HEAD - (void)get_rnd_line("elvish.txt", 0, syllable); - name.append(syllable); -======= - (void)get_random_line("elvish.txt", 0, syllable); - strcat(out_string, syllable); ->>>>>>> dd39ec10b ([Refactor] #2651 Renamed get_rnd_line() to get_random_line()) + ss << get_random_line("elvish.txt", 0).value(); } } + auto name = ss.str(); name[0] = toupper(name[0]); return name; #endif @@ -159,11 +150,10 @@ std::string get_table_name() */ std::string get_table_sindarin_aux() { - char syllable[80]; - get_random_line("sname.txt", 1, syllable); - std::string name = syllable; - get_random_line("sname.txt", 2, syllable); - name.append(syllable); + std::stringstream ss; + ss << get_random_line("sname.txt", 1).value(); + ss << get_random_line("sname.txt", 2).value(); + auto name = ss.str(); return _(sindarin_to_kana(name), name); } diff --git a/src/inventory/inventory-curse.cpp b/src/inventory/inventory-curse.cpp index bcd85f5b2..0f5a1a8fd 100644 --- a/src/inventory/inventory-curse.cpp +++ b/src/inventory/inventory-curse.cpp @@ -34,6 +34,8 @@ #include "util/quarks.h" #include "util/string-processor.h" #include "view/display-messages.h" +#include +#include namespace { const EnumClassFlagGroup TRC_P_FLAG_MASK({ CurseTraitType::TY_CURSE, CurseTraitType::DRAIN_EXP, CurseTraitType::ADD_L_CURSE, CurseTraitType::ADD_H_CURSE, CurseTraitType::CALL_ANIMAL, CurseTraitType::CALL_DEMON, @@ -223,10 +225,11 @@ static void occur_chainsword_effect(PlayerType *player_ptr) return; } - char noise[1024]; - if (!get_random_line(_("chainswd_j.txt", "chainswd.txt"), 0, noise)) { - msg_print(noise); + const auto noise = get_random_line(_("chainswd_j.txt", "chainswd.txt"), 0); + if (noise.has_value()) { + msg_print(noise.value()); } + disturb(player_ptr, false, false); } diff --git a/src/io/files-util.cpp b/src/io/files-util.cpp index cc7ecdbe5..dc6d3cc50 100644 --- a/src/io/files-util.cpp +++ b/src/io/files-util.cpp @@ -91,24 +91,18 @@ errr file_character(PlayerType *player_ptr, concptr name) } /*! - * @brief ファイルからランダムに行を一つ取得する / - * Get a random line from a file + * @brief ファイルからランダムに行を一つ取得する * @param file_name ファイル名 * @param entry 特定条件時のN:タグヘッダID - * @param output 出力先の文字列参照ポインタ - * @return エラーコード - * @details - *
- * Based on the monster speech patch by Matt Graham,
- * 
+ * @return ファイルから取得した行 (但しファイルがなかったり異常値ならばnullopt) */ -errr get_random_line(concptr file_name, int entry, char *output) +std::optional get_random_line(concptr file_name, int entry) { char filename[1024]; path_build(filename, sizeof(filename), ANGBAND_DIR_FILE, file_name); auto *fp = angband_fopen(filename, "r"); if (!fp) { - return -1; + return std::nullopt; } int test; @@ -117,7 +111,7 @@ errr get_random_line(concptr file_name, int entry, char *output) char buf[1024]; if (angband_fgets(fp, buf, sizeof(buf)) != 0) { angband_fclose(fp); - return -1; + return std::nullopt; } line_num++; @@ -128,7 +122,7 @@ errr get_random_line(concptr file_name, int entry, char *output) if (buf[2] == '*') { break; } - + if (buf[2] == 'M') { if (monraces_info[i2enum(entry)].flags1 & RF1_MALE) { break; @@ -144,11 +138,12 @@ errr get_random_line(concptr file_name, int entry, char *output) } else { msg_format("Error in line %d of %s!", line_num, file_name); angband_fclose(fp); - return -1; + return std::nullopt; } } auto counter = 0; + std::string line{}; while (true) { char buf[1024]; while (true) { @@ -170,14 +165,18 @@ errr get_random_line(concptr file_name, int entry, char *output) } if (one_in_(counter + 1)) { - strcpy(output, buf); + line = buf; } counter++; } angband_fclose(fp); - return counter ? 0 : -1; + if (counter > 0) { + return line; + } + + return std::nullopt; } #ifdef JP @@ -191,16 +190,16 @@ errr get_random_line(concptr file_name, int entry, char *output) */ std::optional get_random_line_ja_only(concptr file_name, int entry, int count) { - char line[1024]{}; + std::optional line; for (auto i = 0; i < count; i++) { - auto error = get_random_line(file_name, entry, line); - if (error) { + line = get_random_line(file_name, entry); + if (!line.has_value()) { return std::nullopt; } auto is_kanji = false; - for (auto j = 0; line[j]; j++) { - is_kanji |= iskanji(line[j]); + for (auto c = line.value().data(); *c != '\0'; c++) { + is_kanji |= iskanji(*c); } if (is_kanji) { diff --git a/src/io/files-util.h b/src/io/files-util.h index 00dbe4e8c..85405d605 100644 --- a/src/io/files-util.h +++ b/src/io/files-util.h @@ -27,7 +27,7 @@ class PlayerType; typedef void (*update_playtime_pf)(void); errr file_character(PlayerType *player_ptr, concptr name); -errr get_random_line(concptr file_name, int entry, char *output); +std::optional get_random_line(concptr file_name, int entry); void read_dead_file(char *buf, size_t buf_size); #ifdef JP diff --git a/src/io/input-key-processor.cpp b/src/io/input-key-processor.cpp index 0f9a65533..da7dfc0dc 100644 --- a/src/io/input-key-processor.cpp +++ b/src/io/input-key-processor.cpp @@ -95,6 +95,8 @@ #include "window/display-sub-windows.h" #include "wizard/cmd-wizard.h" #include "world/world.h" +#include +#include /*! * @brief ウィザードモードへの導入処理 @@ -681,10 +683,10 @@ void process_command(PlayerType *player_ptr) flush(); } if (one_in_(2)) { - char error_m[1024]; sound(SOUND_ILLEGAL); - if (!get_random_line(_("error_j.txt", "error.txt"), 0, error_m)) { - msg_print(error_m); + const auto error_mes = get_random_line(_("error_j.txt", "error.txt"), 0); + if (error_mes.has_value()) { + msg_print(error_mes.value()); } } else { prt(_(" '?' でヘルプが表示されます。", "Type '?' for help."), 0, 0); diff --git a/src/monster-floor/monster-move.cpp b/src/monster-floor/monster-move.cpp index 9d1cb387c..abd6049c8 100644 --- a/src/monster-floor/monster-move.cpp +++ b/src/monster-floor/monster-move.cpp @@ -536,15 +536,14 @@ void process_speak_sound(PlayerType *player_ptr, MONSTER_IDX m_idx, POSITION oy, } const auto m_name = m_ptr->ml ? monster_desc(player_ptr, m_ptr, 0) : std::string(_("それ", "It")); - char monmessage[1024]; - auto filename = get_speak_filename(m_ptr); if (filename.empty()) { return; } - if (get_random_line(filename.data(), enum2i(m_ptr->ap_r_idx), monmessage) == 0) { - msg_format(_("%^s%s", "%^s %s"), m_name.data(), monmessage); + const auto monmessage = get_random_line(filename.data(), enum2i(m_ptr->ap_r_idx)); + if (monmessage.has_value()) { + msg_format(_("%^s%s", "%^s %s"), m_name.data(), monmessage->data()); } } diff --git a/src/monster/monster-damage.cpp b/src/monster/monster-damage.cpp index ea1fb9bc9..67eaf685a 100644 --- a/src/monster/monster-damage.cpp +++ b/src/monster/monster-damage.cpp @@ -48,6 +48,8 @@ #include "view/display-messages.h" #include "world/world.h" #include +#include +#include /* * @brief コンストラクタ @@ -335,9 +337,9 @@ void MonsterDamageProcessor::dying_scream(std::string_view m_name) return; } - char line_got[1024]; - if (!get_random_line(_("mondeath_j.txt", "mondeath.txt"), enum2i(m_ptr->r_idx), line_got)) { - msg_format("%^s %s", m_name, line_got); + const auto death_mes = get_random_line(_("mondeath_j.txt", "mondeath.txt"), enum2i(m_ptr->r_idx)); + if (death_mes.has_value()) { + msg_format("%^s %s", m_name, death_mes->data()); } #ifdef WORLD_SCORE diff --git a/src/monster/monster-describer.cpp b/src/monster/monster-describer.cpp index c4772e569..9cc464fff 100644 --- a/src/monster/monster-describer.cpp +++ b/src/monster/monster-describer.cpp @@ -15,6 +15,9 @@ #include "util/quarks.h" #include "util/string-processor.h" #include "view/display-messages.h" +#include +#include +#include /*! * @brief モンスターの呼称を作成する / Build a string describing a monster in some way. @@ -26,13 +29,14 @@ std::string monster_desc(PlayerType *player_ptr, MonsterEntity *m_ptr, BIT_FLAGS { MonsterRaceInfo *r_ptr; r_ptr = &monraces_info[m_ptr->ap_r_idx]; - concptr name = (mode & MD_TRUE_NAME) ? m_ptr->get_real_r_ref().name.data() : r_ptr->name.data(); - GAME_TEXT silly_name[1024]; + std::string_view name = (mode & MD_TRUE_NAME) ? m_ptr->get_real_r_ref().name : r_ptr->name; + std::optional silly_name; bool named = false; auto is_hallucinated = player_ptr->effects()->hallucination()->is_hallucinated(); if (is_hallucinated && !(mode & MD_IGNORE_HALLU)) { if (one_in_(2)) { - if (!get_random_line(_("silly_j.txt", "silly.txt"), enum2i(m_ptr->r_idx), silly_name)) { + silly_name = get_random_line(_("silly_j.txt", "silly.txt"), enum2i(m_ptr->r_idx)); + if (silly_name.has_value()) { named = true; } } @@ -45,10 +49,10 @@ std::string monster_desc(PlayerType *player_ptr, MonsterEntity *m_ptr, BIT_FLAGS hallu_race = &monraces_info[r_idx]; } while (hallu_race->name.empty() || hallu_race->kind_flags.has(MonsterKindType::UNIQUE)); - strcpy(silly_name, (hallu_race->name.data())); + silly_name = hallu_race->name; } - name = silly_name; + name = silly_name.value(); } bool seen = (m_ptr && ((mode & MD_ASSUME_VISIBLE) || (!(mode & MD_ASSUME_HIDDEN) && m_ptr->ml))); @@ -164,16 +168,13 @@ std::string monster_desc(PlayerType *player_ptr, MonsterEntity *m_ptr, BIT_FLAGS std::string desc; if (m_ptr->is_pet() && !m_ptr->is_original_ap()) { #ifdef JP - char *t; - char buf[128]; - strcpy(buf, name); - t = buf; + std::string buf(name); + auto *t = buf.data(); while (strncmp(t, "』", 2) && *t) { t++; } if (*t) { - *t = '\0'; - desc = format("%s?』", buf); + desc = format("%s?』", name); } else { desc = format("%s?", name); } @@ -184,16 +185,13 @@ std::string monster_desc(PlayerType *player_ptr, MonsterEntity *m_ptr, BIT_FLAGS if (r_ptr->kind_flags.has(MonsterKindType::UNIQUE) && !(is_hallucinated && !(mode & MD_IGNORE_HALLU))) { if (m_ptr->mflag2.has(MonsterConstantFlagType::CHAMELEON) && !(mode & MD_TRUE_NAME)) { #ifdef JP - char *t; - char buf[128]; - strcpy(buf, name); - t = buf; + std::string buf(name); + auto *t = buf.data(); while (strncmp(t, "』", 2) && *t) { t++; } if (*t) { - *t = '\0'; - desc = format("%s?』", buf); + desc = format("%s?』", name); } else { desc = format("%s?", name); } diff --git a/src/object-enchant/vorpal-weapon.cpp b/src/object-enchant/vorpal-weapon.cpp index 8bf689224..f6252d185 100644 --- a/src/object-enchant/vorpal-weapon.cpp +++ b/src/object-enchant/vorpal-weapon.cpp @@ -62,9 +62,9 @@ static void print_chainsword_noise(ItemEntity *o_ptr) return; } - char chainsword_noise[1024]; - if (!get_random_line(_("chainswd_j.txt", "chainswd.txt"), 0, chainsword_noise)) { - msg_print(chainsword_noise); + const auto chainsword_noise = get_random_line(_("chainswd_j.txt", "chainswd.txt"), 0); + if (chainsword_noise.has_value()) { + msg_print(chainsword_noise.value()); } } diff --git a/src/player/player-damage.cpp b/src/player/player-damage.cpp index e7ff433f1..36c7b5d1d 100644 --- a/src/player/player-damage.cpp +++ b/src/player/player-damage.cpp @@ -73,6 +73,8 @@ #include "util/string-processor.h" #include "view/display-messages.h" #include "world/world.h" +#include +#include using dam_func = int (*)(PlayerType *player_ptr, int dam, concptr kb_str, bool aura); @@ -295,9 +297,6 @@ int cold_dam(PlayerType *player_ptr, int dam, concptr kb_str, bool aura) int take_hit(PlayerType *player_ptr, int damage_type, int damage, concptr hit_from) { int old_chp = player_ptr->chp; - - char death_message[1024]; - int warning = (player_ptr->mhp * hitpoint_warn / 10); if (player_ptr->is_dead) { return 0; @@ -475,19 +474,21 @@ int take_hit(PlayerType *player_ptr, int damage_type, int damage, concptr hit_fr msg_print(nullptr); } else { + std::optional opt_death_message; if (winning_seppuku) { - get_random_line(_("seppuku_j.txt", "seppuku.txt"), 0, death_message); + opt_death_message = get_random_line(_("seppuku_j.txt", "seppuku.txt"), 0); } else { - get_random_line(_("death_j.txt", "death.txt"), 0, death_message); + opt_death_message = get_random_line(_("death_j.txt", "death.txt"), 0); } + auto &death_message = opt_death_message.value(); do { #ifdef JP - while (!get_string(winning_seppuku ? "辞世の句: " : "断末魔の叫び: ", death_message, sizeof(death_message))) { + while (!get_string(winning_seppuku ? "辞世の句: " : "断末魔の叫び: ", death_message.data(), death_message.length())) { ; } #else - while (!get_string("Last words: ", death_message, 1024)) { + while (!get_string("Last words: ", death_message.data(), 1024)) { ; } #endif @@ -495,12 +496,12 @@ int take_hit(PlayerType *player_ptr, int damage_type, int damage, concptr hit_fr if (death_message[0] == '\0') { #ifdef JP - strcpy(death_message, format("あなたは%sました。", android ? "壊れ" : "死に").data()); + death_message = format("あなたは%sました。", android ? "壊れ" : "死に"); #else - strcpy(death_message, android ? "You are broken." : "You die."); + death_message = android ? "You are broken." : "You die."; #endif } else { - player_ptr->last_message = string_make(death_message); + player_ptr->last_message = string_make(death_message.data()); } #ifdef JP @@ -510,9 +511,6 @@ int take_hit(PlayerType *player_ptr, int damage_type, int damage, concptr hit_fr int h = game_term->hgt; int msg_pos_x[9] = { 5, 7, 9, 12, 14, 17, 19, 21, 23 }; int msg_pos_y[9] = { 3, 4, 5, 4, 5, 4, 5, 6, 4 }; - concptr str; - char *str2; - term_clear(); /* 桜散る */ @@ -520,12 +518,12 @@ int take_hit(PlayerType *player_ptr, int damage_type, int damage, concptr hit_fr term_putstr(randint0(w / 2) * 2, randint0(h), 2, TERM_VIOLET, "υ"); } - str = death_message; + auto str = death_message.data(); if (strncmp(str, "「", 2) == 0) { str += 2; } - str2 = angband_strstr(str, "」"); + auto *str2 = angband_strstr(str, "」"); if (str2 != nullptr) { *str2 = '\0'; } @@ -579,7 +577,11 @@ int take_hit(PlayerType *player_ptr, int damage_type, int damage, concptr hit_fr hit_from = _("何か", "something"); } - exe_write_diary(player_ptr, DIARY_DESCRIPTION, 0, std::string(_(hit_from, "was in a critical situation because of ")).append(_("によってピンチに陥った。", hit_from)).append(_("", ".")).data()); + std::stringstream ss; + ss << _(hit_from, "was in a critical situation because of "); + ss << _("によってピンチに陥った。", hit_from); + ss << _("", "."); + exe_write_diary(player_ptr, DIARY_DESCRIPTION, 0, ss.str().data()); } if (auto_more) { @@ -632,7 +634,10 @@ static void process_aura_damage(MonsterEntity *m_ptr, PlayerType *player_ptr, bo */ void touch_zap_player(MonsterEntity *m_ptr, PlayerType *player_ptr) { - process_aura_damage(m_ptr, player_ptr, has_immune_fire(player_ptr) != 0, MonsterAuraType::FIRE, fire_dam, _("突然とても熱くなった!", "You are suddenly very hot!")); - process_aura_damage(m_ptr, player_ptr, has_immune_cold(player_ptr) != 0, MonsterAuraType::COLD, cold_dam, _("突然とても寒くなった!", "You are suddenly very cold!")); - process_aura_damage(m_ptr, player_ptr, has_immune_elec(player_ptr) != 0, MonsterAuraType::ELEC, elec_dam, _("電撃をくらった!", "You get zapped!")); + constexpr auto fire_mes = _("突然とても熱くなった!", "You are suddenly very hot!"); + constexpr auto cold_mes = _("突然とても寒くなった!", "You are suddenly very cold!"); + constexpr auto elec_mes = _("電撃をくらった!", "You get zapped!"); + process_aura_damage(m_ptr, player_ptr, has_immune_fire(player_ptr) != 0, MonsterAuraType::FIRE, fire_dam, fire_mes); + process_aura_damage(m_ptr, player_ptr, has_immune_cold(player_ptr) != 0, MonsterAuraType::COLD, cold_dam, cold_mes); + process_aura_damage(m_ptr, player_ptr, has_immune_elec(player_ptr) != 0, MonsterAuraType::ELEC, elec_dam, elec_mes); } diff --git a/src/store/rumor.cpp b/src/store/rumor.cpp index 76c15deca..f81a3cb2e 100644 --- a/src/store/rumor.cpp +++ b/src/store/rumor.cpp @@ -94,25 +94,20 @@ static std::pair get_artifact_definition( void display_rumor(PlayerType *player_ptr, bool ex) { int section = (ex && (randint0(3) == 0)) ? 1 : 0; - char rumor[1024]{}; - - // @todo「嘘の噂もある。」は後で統合するため日英分離しない. #ifdef JP - auto tmp_rumor = get_random_line_ja_only("rumors_j.txt", section, 10); - if (tmp_rumor.has_value()) { - strcpy(rumor, tmp_rumor.value().data()); - } else { - strcpy(rumor, _("嘘の噂もある。", "Some rumors are wrong.")); - } + auto opt_rumor = get_random_line_ja_only("rumors_j.txt", section, 10); #else - errr err = get_random_line("rumors.txt", section, rumor); - if (err) { - strcpy(rumor, _("嘘の噂もある。", "Some rumors are wrong.")); - } + auto opt_rumor = get_random_line("rumors.txt", section); #endif + std::string rumor; + if (opt_rumor.has_value()) { + rumor = opt_rumor.value().data(); + } else { + rumor = _("嘘の噂もある。", "Some rumors are wrong."); + } - if (strncmp(rumor, "R:", 2) != 0) { - msg_format("%s", rumor); + if (strncmp(rumor.data(), "R:", 2) != 0) { + msg_print(rumor); return; }