OSDN Git Service

[Refactor] #40236 Separated do_cmd_knowledge_monsters() and similar functions from...
authorHourier <hourier@users.sourceforge.jp>
Fri, 24 Apr 2020 08:00:11 +0000 (17:00 +0900)
committerHourier <hourier@users.sourceforge.jp>
Fri, 24 Apr 2020 08:00:11 +0000 (17:00 +0900)
Hengband_vcs2017/Hengband/Hengband.vcxproj
Hengband_vcs2017/Hengband/Hengband.vcxproj.filters
src/Makefile.am
src/character-dump.c
src/cmd/cmd-dump.c
src/cmd/cmd-dump.h
src/cmd/cmd-visuals.c
src/knowledge/knowledge-monsters.c [new file with mode: 0644]
src/knowledge/knowledge-monsters.h [new file with mode: 0644]

index 4a593a4..084e601 100644 (file)
     <ClCompile Include="..\..\src\cmd\dump-util.c" />\r
     <ClCompile Include="..\..\src\knowledge\knowledge-artifacts.c" />\r
     <ClCompile Include="..\..\src\knowledge\knowledge-experiences.c" />\r
+    <ClCompile Include="..\..\src\knowledge\knowledge-monsters.c" />\r
     <ClCompile Include="..\..\src\knowledge\knowledge-quests.c" />\r
     <ClCompile Include="..\..\src\knowledge\knowledge-self.c" />\r
     <ClCompile Include="..\..\src\knowledge\knowledge-uniques.c" />\r
     <ClInclude Include="..\..\src\cmd\dump-util.h" />\r
     <ClInclude Include="..\..\src\knowledge\knowledge-artifacts.h" />\r
     <ClInclude Include="..\..\src\knowledge\knowledge-experiences.h" />\r
+    <ClInclude Include="..\..\src\knowledge\knowledge-monsters.h" />\r
     <ClInclude Include="..\..\src\knowledge\knowledge-quests.h" />\r
     <ClInclude Include="..\..\src\knowledge\knowledge-self.h" />\r
     <ClInclude Include="..\..\src\knowledge\knowledge-uniques.h" />\r
index 680a44c..890e915 100644 (file)
     <ClCompile Include="..\..\src\knowledge\knowledge-self.c">
       <Filter>knowledge</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\knowledge\knowledge-monsters.c">
+      <Filter>knowledge</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\src\gamevalue.h" />
     <ClInclude Include="..\..\src\knowledge\knowledge-self.h">
       <Filter>knowledge</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\knowledge\knowledge-monsters.h">
+      <Filter>knowledge</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\..\src\wall.bmp" />
index 5780253..ac72ce0 100644 (file)
@@ -151,6 +151,7 @@ hengband_SOURCES = \
        \
        knowledge/knowledge-artifacts.c knowledge/knowledge-artifacts.h \
        knowledge/knowledge-experiences.c knowledge/knowledge-experiences.h \
+       knowledge/knowledge-monsters.c knowledge/knowledge-monsters.h \
        knowledge/knowledge-uniques.c knowledge/knowledge-uniques.h \
        knowledge/knowledge-self.c knowledge/knowledge-self.h \
        knowledge/knowledge-quests.c knowledge/knowledge-quests.h \
index eed5bb1..212224e 100644 (file)
@@ -11,7 +11,7 @@
 #include "init.h"
 #include "mutation.h"
 #include "object-flavor.h"
-#include "cmd/cmd-dump.h"
+#include "knowledge/knowledge-quests.h"
 #include "io/special-class-dump.h"
 #include "io/player-status-dump.h"
 #include "io/write-diary.h"
index a2575ca..83ab462 100644 (file)
@@ -45,6 +45,7 @@
 
 #include "knowledge/knowledge-artifacts.h"
 #include "knowledge/knowledge-experiences.h"
+#include "knowledge/knowledge-monsters.h"
 #include "knowledge/knowledge-quests.h"
 #include "knowledge/knowledge-self.h"
 #include "knowledge/knowledge-uniques.h"
 #include "market/store.h"
 #include "artifact.h"
 #include "object-flavor.h"
-#include "monster-status.h"
 #include "object/object-kind.h"
 #include "floor-town.h"
 #include "cmd/feeling-table.h"
-#include "cmd/monster-group-table.h"
 #include "cmd/object-group-table.h"
 #include "market/store-util.h"
 #include "view-mainwindow.h" // 暫定。後で消す
@@ -417,77 +416,6 @@ void do_cmd_feeling(player_type *creature_ptr)
 
 
 /*
- * todo 引数と戻り値について追記求む
- * Build a list of monster indexes in the given group.
- *
- * mode & 0x01 : check for non-empty group
- * mode & 0x02 : visual operation only
-
- * @param creature_ptr プレーヤーへの参照ポインタ
- * @param grp_cur ???
- * @param mon_idx[] ???
- * @param mode ???
- * @return The number of monsters in the group
- */
-static IDX collect_monsters(player_type *creature_ptr, IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
-{
-       concptr group_char = monster_group_char[grp_cur];
-       bool grp_unique = (monster_group_char[grp_cur] == (char *)-1L);
-       bool grp_riding = (monster_group_char[grp_cur] == (char *)-2L);
-       bool grp_wanted = (monster_group_char[grp_cur] == (char *)-3L);
-       bool grp_amberite = (monster_group_char[grp_cur] == (char *)-4L);
-
-       IDX mon_cnt = 0;
-       for (IDX i = 0; i < max_r_idx; i++)
-       {
-               monster_race *r_ptr = &r_info[i];
-               if (!r_ptr->name) continue;
-               if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
-
-               if (grp_unique)
-               {
-                       if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
-               }
-               else if (grp_riding)
-               {
-                       if (!(r_ptr->flags7 & RF7_RIDING)) continue;
-               }
-               else if (grp_wanted)
-               {
-                       bool wanted = FALSE;
-                       for (int j = 0; j < MAX_BOUNTY; j++)
-                       {
-                               if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
-                                       (creature_ptr->today_mon && creature_ptr->today_mon == i))
-                               {
-                                       wanted = TRUE;
-                                       break;
-                               }
-                       }
-
-                       if (!wanted) continue;
-               }
-               else if (grp_amberite)
-               {
-                       if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
-               }
-               else
-               {
-                       if (!my_strchr(group_char, r_ptr->d_char)) continue;
-               }
-
-               mon_idx[mon_cnt++] = i;
-               if (mode & 0x01) break;
-       }
-
-       mon_idx[mon_cnt] = -1;
-       int dummy_why;
-       ang_sort(mon_idx, &dummy_why, mon_cnt, ang_sort_comp_monster_level, ang_sort_swap_hook);
-       return mon_cnt;
-}
-
-
-/*
  * Build a list of object indexes in the given group. Return the number
  * of objects in the group.
  *
@@ -565,410 +493,6 @@ static FEAT_IDX collect_features(FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
 }
 
 
-/*!
- * @brief 現在のペットを表示するコマンドのメインルーチン /
- * Display current pets
- * @param creature_ptr プレーヤーへの参照ポインタ
- * @return なし
- */
-static void do_cmd_knowledge_pets(player_type *creature_ptr)
-{
-       FILE *fff = NULL;
-       GAME_TEXT file_name[FILE_NAME_SIZE];
-       if (!open_temporary_file(&fff, file_name)) return;
-
-       monster_type *m_ptr;
-       GAME_TEXT pet_name[MAX_NLEN];
-       int t_friends = 0;
-       for (int i = creature_ptr->current_floor_ptr->m_max - 1; i >= 1; i--)
-       {
-               m_ptr = &creature_ptr->current_floor_ptr->m_list[i];
-               if (!monster_is_valid(m_ptr)) continue;
-               if (!is_pet(m_ptr)) continue;
-
-               t_friends++;
-               monster_desc(creature_ptr, pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
-               fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
-       }
-
-       int show_upkeep = calculate_upkeep(creature_ptr);
-
-       fprintf(fff, "----------------------------------------------\n");
-#ifdef JP
-       fprintf(fff, "    合計: %d 体のペット\n", t_friends);
-#else
-       fprintf(fff, "   Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
-#endif
-       fprintf(fff, _(" 維持コスト: %d%% MP\n", "   Upkeep: %d%% mana.\n"), show_upkeep);
-
-       my_fclose(fff);
-       (void)show_file(creature_ptr, TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
-       fd_kill(file_name);
-}
-
-
-/*!
- * @brief 現在までに倒したモンスターを表示するコマンドのメインルーチン /
- * @param creature_ptr プレーヤーへの参照ポインタ
- * Total kill count
- * @return なし
- * @note the player ghosts are ignored.
- */
-static void do_cmd_knowledge_kill_count(player_type *creature_ptr)
-{
-       FILE *fff = NULL;
-       GAME_TEXT file_name[FILE_NAME_SIZE];
-       if (!open_temporary_file(&fff, file_name)) return;
-
-       MONRACE_IDX *who;
-       C_MAKE(who, max_r_idx, MONRACE_IDX);
-       s32b total = 0;
-       for (int kk = 1; kk < max_r_idx; kk++)
-       {
-               monster_race *r_ptr = &r_info[kk];
-
-               if (r_ptr->flags1 & (RF1_UNIQUE))
-               {
-                       bool dead = (r_ptr->max_num == 0);
-
-                       if (dead)
-                       {
-                               total++;
-                       }
-               }
-               else
-               {
-                       MONSTER_NUMBER this_monster = r_ptr->r_pkills;
-
-                       if (this_monster > 0)
-                       {
-                               total += this_monster;
-                       }
-               }
-       }
-
-       if (total < 1)
-               fprintf(fff, _("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
-       else
-#ifdef JP
-               fprintf(fff, "あなたは%ld体の敵を倒している。\n\n", (long int)total);
-#else
-               fprintf(fff, "You have defeated %ld %s.\n\n", (long int)total, (total == 1) ? "enemy" : "enemies");
-#endif
-
-       total = 0;
-       int n = 0;
-       for (MONRACE_IDX i = 1; i < max_r_idx; i++)
-       {
-               monster_race *r_ptr = &r_info[i];
-               if (r_ptr->name) who[n++] = i;
-       }
-
-       u16b why = 2;
-       ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
-       for (int k = 0; k < n; k++)
-       {
-               monster_race *r_ptr = &r_info[who[k]];
-               if (r_ptr->flags1 & (RF1_UNIQUE))
-               {
-                       bool dead = (r_ptr->max_num == 0);
-                       if (dead)
-                       {
-                               fprintf(fff, "     %s\n", (r_name + r_ptr->name));
-                               total++;
-                       }
-
-                       continue;
-               }
-
-               MONSTER_NUMBER this_monster = r_ptr->r_pkills;
-               if (this_monster <= 0) continue;
-
-#ifdef JP
-               if (my_strchr("pt", r_ptr->d_char))
-                       fprintf(fff, "     %3d 人の %s\n", (int)this_monster, r_name + r_ptr->name);
-               else
-                       fprintf(fff, "     %3d 体の %s\n", (int)this_monster, r_name + r_ptr->name);
-#else
-               if (this_monster < 2)
-               {
-                       if (my_strstr(r_name + r_ptr->name, "coins"))
-                       {
-                               fprintf(fff, "     1 pile of %s\n", (r_name + r_ptr->name));
-                       }
-                       else
-                       {
-                               fprintf(fff, "     1 %s\n", (r_name + r_ptr->name));
-                       }
-               }
-               else
-               {
-                       char ToPlural[80];
-                       strcpy(ToPlural, (r_name + r_ptr->name));
-                       plural_aux(ToPlural);
-                       fprintf(fff, "     %d %s\n", this_monster, ToPlural);
-               }
-#endif
-               total += this_monster;
-       }
-
-       fprintf(fff, "----------------------------------------------\n");
-#ifdef JP
-       fprintf(fff, "    合計: %lu 体を倒した。\n", (unsigned long int)total);
-#else
-       fprintf(fff, "   Total: %lu creature%s killed.\n", (unsigned long int)total, (total == 1 ? "" : "s"));
-#endif
-
-       C_KILL(who, max_r_idx, s16b);
-       my_fclose(fff);
-       (void)show_file(creature_ptr, TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
-       fd_kill(file_name);
-}
-
-
-/*
- * Display the monsters in a group.
- */
-static void display_monster_list(int col, int row, int per_page, s16b mon_idx[], int mon_cur, int mon_top, bool visual_only)
-{
-       int i;
-       for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
-       {
-               TERM_COLOR attr;
-               MONRACE_IDX r_idx = mon_idx[mon_top + i];
-               monster_race *r_ptr = &r_info[r_idx];
-               attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
-               c_prt(attr, (r_name + r_ptr->name), row + i, col);
-               if (per_page == 1)
-               {
-                       c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (current_world_ptr->wizard || visual_only) ? 56 : 61);
-               }
-
-               if (current_world_ptr->wizard || visual_only)
-               {
-                       c_prt(attr, format("%d", r_idx), row + i, 62);
-               }
-
-               Term_erase(69, row + i, 255);
-               Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
-               if (!visual_only)
-               {
-                       if (!(r_ptr->flags1 & RF1_UNIQUE))
-                               put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
-                       else
-                               c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
-                               (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
-               }
-       }
-
-       for (; i < per_page; i++)
-       {
-               Term_erase(col, row + i, 255);
-       }
-}
-
-
-/*
- * todo 引数の詳細について加筆求む
- * Display known monsters.
- * @param creature_ptr プレーヤーへの参照ポインタ
- * @param need_redraw 画面の再描画が必要な時TRUE
- * @param visual_only ???
- * @param direct_r_idx モンスターID
- * @return なし
- */
-void do_cmd_knowledge_monsters(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_r_idx)
-{
-       TERM_LEN wid, hgt;
-       Term_get_size(&wid, &hgt);
-       IDX *mon_idx;
-       C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
-
-       int max = 0;
-       IDX grp_cnt = 0;
-       IDX grp_idx[100];
-       IDX mon_cnt;
-       bool visual_list = FALSE;
-       TERM_COLOR attr_top = 0;
-       byte char_left = 0;
-       BIT_FLAGS8 mode;
-       int browser_rows = hgt - 8;
-       if (direct_r_idx < 0)
-       {
-               mode = visual_only ? 0x03 : 0x01;
-               int len;
-               for (IDX i = 0; monster_group_text[i] != NULL; i++)
-               {
-                       len = strlen(monster_group_text[i]);
-                       if (len > max) max = len;
-
-                       if ((monster_group_char[i] == ((char *)-1L)) || collect_monsters(creature_ptr, i, mon_idx, mode))
-                       {
-                               grp_idx[grp_cnt++] = i;
-                       }
-               }
-
-               mon_cnt = 0;
-       }
-       else
-       {
-               mon_idx[0] = direct_r_idx;
-               mon_cnt = 1;
-               mon_idx[1] = -1;
-
-               (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
-                       &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
-       }
-
-       grp_idx[grp_cnt] = -1;
-       mode = visual_only ? 0x02 : 0x00;
-       IDX old_grp_cur = -1;
-       IDX grp_cur = 0;
-       IDX grp_top = 0;
-       IDX mon_cur = 0;
-       IDX mon_top = 0;
-       int column = 0;
-       bool flag = FALSE;
-       bool redraw = TRUE;
-       while (!flag)
-       {
-               if (redraw)
-               {
-                       clear_from(0);
-                       prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
-                       if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
-                       prt(_("名前", "Name"), 4, max + 3);
-                       if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
-                       prt(_("文字", "Sym"), 4, 67);
-                       if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
-
-                       for (IDX i = 0; i < 78; i++)
-                       {
-                               Term_putch(i, 5, TERM_WHITE, '=');
-                       }
-
-                       if (direct_r_idx < 0)
-                       {
-                               for (IDX i = 0; i < browser_rows; i++)
-                               {
-                                       Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
-                               }
-                       }
-
-                       redraw = FALSE;
-               }
-
-               if (direct_r_idx < 0)
-               {
-                       if (grp_cur < grp_top) grp_top = grp_cur;
-                       if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
-
-                       display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
-                       if (old_grp_cur != grp_cur)
-                       {
-                               old_grp_cur = grp_cur;
-                               mon_cnt = collect_monsters(creature_ptr, grp_idx[grp_cur], mon_idx, mode);
-                       }
-
-                       while (mon_cur < mon_top)
-                               mon_top = MAX(0, mon_top - browser_rows / 2);
-                       while (mon_cur >= mon_top + browser_rows)
-                               mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows / 2);
-               }
-
-               if (!visual_list)
-               {
-                       display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
-               }
-               else
-               {
-                       mon_top = mon_cur;
-                       display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
-                       display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
-               }
-
-               prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
-                       (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
-                       visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
-                       (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
-                       hgt - 1, 0);
-
-               monster_race *r_ptr;
-               r_ptr = &r_info[mon_idx[mon_cur]];
-
-               if (!visual_only)
-               {
-                       if (mon_cnt) monster_race_track(creature_ptr, mon_idx[mon_cur]);
-                       handle_stuff(creature_ptr);
-               }
-
-               if (visual_list)
-               {
-                       place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
-               }
-               else if (!column)
-               {
-                       Term_gotoxy(0, 6 + (grp_cur - grp_top));
-               }
-               else
-               {
-                       Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
-               }
-
-               char ch = inkey();
-               if (visual_mode_command(ch, &visual_list, browser_rows - 1, wid - (max + 3), &attr_top, &char_left, &r_ptr->x_attr, &r_ptr->x_char, need_redraw))
-               {
-                       if (direct_r_idx >= 0)
-                       {
-                               switch (ch)
-                               {
-                               case '\n':
-                               case '\r':
-                               case ESCAPE:
-                                       flag = TRUE;
-                                       break;
-                               }
-                       }
-
-                       continue;
-               }
-
-               switch (ch)
-               {
-               case ESCAPE:
-               {
-                       flag = TRUE;
-                       break;
-               }
-
-               case 'R':
-               case 'r':
-               {
-                       if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
-                       {
-                               screen_roff(creature_ptr, mon_idx[mon_cur], 0);
-
-                               (void)inkey();
-
-                               redraw = TRUE;
-                       }
-
-                       break;
-               }
-
-               default:
-               {
-                       browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
-
-                       break;
-               }
-               }
-       }
-
-       C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
-}
-
-
 /*
  * Display the objects in a group.
  */
@@ -1618,44 +1142,6 @@ void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f
 
 
 /*
- * List wanted monsters
- * @param creature_ptr プレーヤーへの参照ポインタ
- * @return なし
- */
-static void do_cmd_knowledge_bounty(player_type *creature_ptr)
-{
-       FILE *fff = NULL;
-       GAME_TEXT file_name[FILE_NAME_SIZE];
-       if (!open_temporary_file(&fff, file_name)) return;
-
-       fprintf(fff, _("今日のターゲット : %s\n", "Today's target : %s\n"),
-               (creature_ptr->today_mon ? r_name + r_info[creature_ptr->today_mon].name : _("不明", "unknown")));
-       fprintf(fff, "\n");
-       fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
-       fprintf(fff, "----------------------------------------------\n");
-
-       bool listed = FALSE;
-       for (int i = 0; i < MAX_BOUNTY; i++)
-       {
-               if (current_world_ptr->bounty_r_idx[i] <= 10000)
-               {
-                       fprintf(fff, "%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
-                       listed = TRUE;
-               }
-       }
-
-       if (!listed)
-       {
-               fprintf(fff, "\n%s\n", _("賞金首はもう残っていません。", "There are no more wanted monster."));
-       }
-
-       my_fclose(fff);
-       (void)show_file(creature_ptr, TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
-       fd_kill(file_name);
-}
-
-
-/*
  * Dungeon
  */
 static void do_cmd_knowledge_dungeon(player_type *creature_ptr)
index f5b3db9..a58dfd1 100644 (file)
@@ -19,6 +19,5 @@ extern void do_cmd_spoilers(player_type *creature_ptr);
 extern void spoil_random_artifact(player_type *creature_ptr, concptr fname);
 
 /* 暫定。後で移す. */
-void do_cmd_knowledge_monsters(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_r_idx);
 void do_cmd_knowledge_objects(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_k_idx);
 void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
index 2f82197..49a6fe5 100644 (file)
@@ -2,6 +2,7 @@
 #include "cmd/cmd-visuals.h"
 #include "cmd/cmd-draw.h"
 #include "cmd/cmd-dump.h" // 暫定。後で消す.
+#include "knowledge/knowledge-monsters.h"
 #include "files.h"
 #include "object/object-kind.h"
 #include "object-flavor.h"
diff --git a/src/knowledge/knowledge-monsters.c b/src/knowledge/knowledge-monsters.c
new file mode 100644 (file)
index 0000000..9250330
--- /dev/null
@@ -0,0 +1,531 @@
+/*!
+ * todo サブルーチン分割を行うと行数が膨れ上がりそう、再分割も検討すべし
+ * @brief 既知のモンスターに関する情報を表示する
+ * @date 2020/04/24
+ * @author Hourier
+ */
+
+#include "angband.h"
+#include "knowledge/knowledge-monsters.h"
+#include "cmd/dump-util.h"
+#include "sort.h"
+#include "cmd/monster-group-table.h"
+#include "monster-status.h"
+#include "world.h"
+#include "core/show-file.h"
+#include "gameterm.h"
+
+#include "core.h" // 暫定、後で消す.
+#include "view-mainwindow.h" // 暫定、後で消す.
+
+ /*
+  * todo 引数と戻り値について追記求む
+  * Build a list of monster indexes in the given group.
+  *
+  * mode & 0x01 : check for non-empty group
+  * mode & 0x02 : visual operation only
+
+  * @param creature_ptr プレーヤーへの参照ポインタ
+  * @param grp_cur ???
+  * @param mon_idx[] ???
+  * @param mode ???
+  * @return The number of monsters in the group
+  */
+static IDX collect_monsters(player_type *creature_ptr, IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
+{
+       concptr group_char = monster_group_char[grp_cur];
+       bool grp_unique = (monster_group_char[grp_cur] == (char *)-1L);
+       bool grp_riding = (monster_group_char[grp_cur] == (char *)-2L);
+       bool grp_wanted = (monster_group_char[grp_cur] == (char *)-3L);
+       bool grp_amberite = (monster_group_char[grp_cur] == (char *)-4L);
+
+       IDX mon_cnt = 0;
+       for (IDX i = 0; i < max_r_idx; i++)
+       {
+               monster_race *r_ptr = &r_info[i];
+               if (!r_ptr->name) continue;
+               if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
+
+               if (grp_unique)
+               {
+                       if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
+               }
+               else if (grp_riding)
+               {
+                       if (!(r_ptr->flags7 & RF7_RIDING)) continue;
+               }
+               else if (grp_wanted)
+               {
+                       bool wanted = FALSE;
+                       for (int j = 0; j < MAX_BOUNTY; j++)
+                       {
+                               if (current_world_ptr->bounty_r_idx[j] == i || current_world_ptr->bounty_r_idx[j] - 10000 == i ||
+                                       (creature_ptr->today_mon && creature_ptr->today_mon == i))
+                               {
+                                       wanted = TRUE;
+                                       break;
+                               }
+                       }
+
+                       if (!wanted) continue;
+               }
+               else if (grp_amberite)
+               {
+                       if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
+               }
+               else
+               {
+                       if (!my_strchr(group_char, r_ptr->d_char)) continue;
+               }
+
+               mon_idx[mon_cnt++] = i;
+               if (mode & 0x01) break;
+       }
+
+       mon_idx[mon_cnt] = -1;
+       int dummy_why;
+       ang_sort(mon_idx, &dummy_why, mon_cnt, ang_sort_comp_monster_level, ang_sort_swap_hook);
+       return mon_cnt;
+}
+
+
+/*!
+ * @brief 現在のペットを表示するコマンドのメインルーチン /
+ * Display current pets
+ * @param creature_ptr プレーヤーへの参照ポインタ
+ * @return なし
+ */
+void do_cmd_knowledge_pets(player_type *creature_ptr)
+{
+       FILE *fff = NULL;
+       GAME_TEXT file_name[FILE_NAME_SIZE];
+       if (!open_temporary_file(&fff, file_name)) return;
+
+       monster_type *m_ptr;
+       GAME_TEXT pet_name[MAX_NLEN];
+       int t_friends = 0;
+       for (int i = creature_ptr->current_floor_ptr->m_max - 1; i >= 1; i--)
+       {
+               m_ptr = &creature_ptr->current_floor_ptr->m_list[i];
+               if (!monster_is_valid(m_ptr)) continue;
+               if (!is_pet(m_ptr)) continue;
+
+               t_friends++;
+               monster_desc(creature_ptr, pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
+               fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
+       }
+
+       int show_upkeep = calculate_upkeep(creature_ptr);
+
+       fprintf(fff, "----------------------------------------------\n");
+#ifdef JP
+       fprintf(fff, "    合計: %d 体のペット\n", t_friends);
+#else
+       fprintf(fff, "   Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
+#endif
+       fprintf(fff, _(" 維持コスト: %d%% MP\n", "   Upkeep: %d%% mana.\n"), show_upkeep);
+
+       my_fclose(fff);
+       (void)show_file(creature_ptr, TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
+       fd_kill(file_name);
+}
+
+
+/*!
+ * @brief 現在までに倒したモンスターを表示するコマンドのメインルーチン /
+ * @param creature_ptr プレーヤーへの参照ポインタ
+ * Total kill count
+ * @return なし
+ * @note the player ghosts are ignored.
+ */
+void do_cmd_knowledge_kill_count(player_type *creature_ptr)
+{
+       FILE *fff = NULL;
+       GAME_TEXT file_name[FILE_NAME_SIZE];
+       if (!open_temporary_file(&fff, file_name)) return;
+
+       MONRACE_IDX *who;
+       C_MAKE(who, max_r_idx, MONRACE_IDX);
+       s32b total = 0;
+       for (int kk = 1; kk < max_r_idx; kk++)
+       {
+               monster_race *r_ptr = &r_info[kk];
+
+               if (r_ptr->flags1 & (RF1_UNIQUE))
+               {
+                       bool dead = (r_ptr->max_num == 0);
+
+                       if (dead)
+                       {
+                               total++;
+                       }
+               }
+               else
+               {
+                       MONSTER_NUMBER this_monster = r_ptr->r_pkills;
+
+                       if (this_monster > 0)
+                       {
+                               total += this_monster;
+                       }
+               }
+       }
+
+       if (total < 1)
+               fprintf(fff, _("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
+       else
+#ifdef JP
+               fprintf(fff, "あなたは%ld体の敵を倒している。\n\n", (long int)total);
+#else
+               fprintf(fff, "You have defeated %ld %s.\n\n", (long int)total, (total == 1) ? "enemy" : "enemies");
+#endif
+
+       total = 0;
+       int n = 0;
+       for (MONRACE_IDX i = 1; i < max_r_idx; i++)
+       {
+               monster_race *r_ptr = &r_info[i];
+               if (r_ptr->name) who[n++] = i;
+       }
+
+       u16b why = 2;
+       ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook);
+       for (int k = 0; k < n; k++)
+       {
+               monster_race *r_ptr = &r_info[who[k]];
+               if (r_ptr->flags1 & (RF1_UNIQUE))
+               {
+                       bool dead = (r_ptr->max_num == 0);
+                       if (dead)
+                       {
+                               fprintf(fff, "     %s\n", (r_name + r_ptr->name));
+                               total++;
+                       }
+
+                       continue;
+               }
+
+               MONSTER_NUMBER this_monster = r_ptr->r_pkills;
+               if (this_monster <= 0) continue;
+
+#ifdef JP
+               if (my_strchr("pt", r_ptr->d_char))
+                       fprintf(fff, "     %3d 人の %s\n", (int)this_monster, r_name + r_ptr->name);
+               else
+                       fprintf(fff, "     %3d 体の %s\n", (int)this_monster, r_name + r_ptr->name);
+#else
+               if (this_monster < 2)
+               {
+                       if (my_strstr(r_name + r_ptr->name, "coins"))
+                       {
+                               fprintf(fff, "     1 pile of %s\n", (r_name + r_ptr->name));
+                       }
+                       else
+                       {
+                               fprintf(fff, "     1 %s\n", (r_name + r_ptr->name));
+                       }
+               }
+               else
+               {
+                       char ToPlural[80];
+                       strcpy(ToPlural, (r_name + r_ptr->name));
+                       plural_aux(ToPlural);
+                       fprintf(fff, "     %d %s\n", this_monster, ToPlural);
+               }
+#endif
+               total += this_monster;
+       }
+
+       fprintf(fff, "----------------------------------------------\n");
+#ifdef JP
+       fprintf(fff, "    合計: %lu 体を倒した。\n", (unsigned long int)total);
+#else
+       fprintf(fff, "   Total: %lu creature%s killed.\n", (unsigned long int)total, (total == 1 ? "" : "s"));
+#endif
+
+       C_KILL(who, max_r_idx, s16b);
+       my_fclose(fff);
+       (void)show_file(creature_ptr, TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
+       fd_kill(file_name);
+}
+
+
+/*
+ * Display the monsters in a group.
+ */
+static void display_monster_list(int col, int row, int per_page, s16b mon_idx[], int mon_cur, int mon_top, bool visual_only)
+{
+       int i;
+       for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
+       {
+               TERM_COLOR attr;
+               MONRACE_IDX r_idx = mon_idx[mon_top + i];
+               monster_race *r_ptr = &r_info[r_idx];
+               attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
+               c_prt(attr, (r_name + r_ptr->name), row + i, col);
+               if (per_page == 1)
+               {
+                       c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (current_world_ptr->wizard || visual_only) ? 56 : 61);
+               }
+
+               if (current_world_ptr->wizard || visual_only)
+               {
+                       c_prt(attr, format("%d", r_idx), row + i, 62);
+               }
+
+               Term_erase(69, row + i, 255);
+               Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
+               if (!visual_only)
+               {
+                       if (!(r_ptr->flags1 & RF1_UNIQUE))
+                               put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
+                       else
+                               c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
+                               (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
+               }
+       }
+
+       for (; i < per_page; i++)
+       {
+               Term_erase(col, row + i, 255);
+       }
+}
+
+
+/*
+ * todo 引数の詳細について加筆求む
+ * Display known monsters.
+ * @param creature_ptr プレーヤーへの参照ポインタ
+ * @param need_redraw 画面の再描画が必要な時TRUE
+ * @param visual_only ???
+ * @param direct_r_idx モンスターID
+ * @return なし
+ */
+void do_cmd_knowledge_monsters(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_r_idx)
+{
+       TERM_LEN wid, hgt;
+       Term_get_size(&wid, &hgt);
+       IDX *mon_idx;
+       C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
+
+       int max = 0;
+       IDX grp_cnt = 0;
+       IDX grp_idx[100];
+       IDX mon_cnt;
+       bool visual_list = FALSE;
+       TERM_COLOR attr_top = 0;
+       byte char_left = 0;
+       BIT_FLAGS8 mode;
+       int browser_rows = hgt - 8;
+       if (direct_r_idx < 0)
+       {
+               mode = visual_only ? 0x03 : 0x01;
+               int len;
+               for (IDX i = 0; monster_group_text[i] != NULL; i++)
+               {
+                       len = strlen(monster_group_text[i]);
+                       if (len > max) max = len;
+
+                       if ((monster_group_char[i] == ((char *)-1L)) || collect_monsters(creature_ptr, i, mon_idx, mode))
+                       {
+                               grp_idx[grp_cnt++] = i;
+                       }
+               }
+
+               mon_cnt = 0;
+       }
+       else
+       {
+               mon_idx[0] = direct_r_idx;
+               mon_cnt = 1;
+               mon_idx[1] = -1;
+
+               (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
+                       &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
+       }
+
+       grp_idx[grp_cnt] = -1;
+       mode = visual_only ? 0x02 : 0x00;
+       IDX old_grp_cur = -1;
+       IDX grp_cur = 0;
+       IDX grp_top = 0;
+       IDX mon_cur = 0;
+       IDX mon_top = 0;
+       int column = 0;
+       bool flag = FALSE;
+       bool redraw = TRUE;
+       while (!flag)
+       {
+               if (redraw)
+               {
+                       clear_from(0);
+                       prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
+                       if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
+                       prt(_("名前", "Name"), 4, max + 3);
+                       if (current_world_ptr->wizard || visual_only) prt("Idx", 4, 62);
+                       prt(_("文字", "Sym"), 4, 67);
+                       if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
+
+                       for (IDX i = 0; i < 78; i++)
+                       {
+                               Term_putch(i, 5, TERM_WHITE, '=');
+                       }
+
+                       if (direct_r_idx < 0)
+                       {
+                               for (IDX i = 0; i < browser_rows; i++)
+                               {
+                                       Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
+                               }
+                       }
+
+                       redraw = FALSE;
+               }
+
+               if (direct_r_idx < 0)
+               {
+                       if (grp_cur < grp_top) grp_top = grp_cur;
+                       if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
+
+                       display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
+                       if (old_grp_cur != grp_cur)
+                       {
+                               old_grp_cur = grp_cur;
+                               mon_cnt = collect_monsters(creature_ptr, grp_idx[grp_cur], mon_idx, mode);
+                       }
+
+                       while (mon_cur < mon_top)
+                               mon_top = MAX(0, mon_top - browser_rows / 2);
+                       while (mon_cur >= mon_top + browser_rows)
+                               mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows / 2);
+               }
+
+               if (!visual_list)
+               {
+                       display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
+               }
+               else
+               {
+                       mon_top = mon_cur;
+                       display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
+                       display_visual_list(max + 3, 7, browser_rows - 1, wid - (max + 3), attr_top, char_left);
+               }
+
+               prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
+                       (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
+                       visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
+                       (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
+                       hgt - 1, 0);
+
+               monster_race *r_ptr;
+               r_ptr = &r_info[mon_idx[mon_cur]];
+
+               if (!visual_only)
+               {
+                       if (mon_cnt) monster_race_track(creature_ptr, mon_idx[mon_cur]);
+                       handle_stuff(creature_ptr);
+               }
+
+               if (visual_list)
+               {
+                       place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
+               }
+               else if (!column)
+               {
+                       Term_gotoxy(0, 6 + (grp_cur - grp_top));
+               }
+               else
+               {
+                       Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
+               }
+
+               char ch = inkey();
+               if (visual_mode_command(ch, &visual_list, browser_rows - 1, wid - (max + 3), &attr_top, &char_left, &r_ptr->x_attr, &r_ptr->x_char, need_redraw))
+               {
+                       if (direct_r_idx >= 0)
+                       {
+                               switch (ch)
+                               {
+                               case '\n':
+                               case '\r':
+                               case ESCAPE:
+                                       flag = TRUE;
+                                       break;
+                               }
+                       }
+
+                       continue;
+               }
+
+               switch (ch)
+               {
+               case ESCAPE:
+               {
+                       flag = TRUE;
+                       break;
+               }
+
+               case 'R':
+               case 'r':
+               {
+                       if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
+                       {
+                               screen_roff(creature_ptr, mon_idx[mon_cur], 0);
+
+                               (void)inkey();
+
+                               redraw = TRUE;
+                       }
+
+                       break;
+               }
+
+               default:
+               {
+                       browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
+
+                       break;
+               }
+               }
+       }
+
+       C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
+}
+
+
+/*
+ * List wanted monsters
+ * @param creature_ptr プレーヤーへの参照ポインタ
+ * @return なし
+ */
+void do_cmd_knowledge_bounty(player_type *creature_ptr)
+{
+       FILE *fff = NULL;
+       GAME_TEXT file_name[FILE_NAME_SIZE];
+       if (!open_temporary_file(&fff, file_name)) return;
+
+       fprintf(fff, _("今日のターゲット : %s\n", "Today's target : %s\n"),
+               (creature_ptr->today_mon ? r_name + r_info[creature_ptr->today_mon].name : _("不明", "unknown")));
+       fprintf(fff, "\n");
+       fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
+       fprintf(fff, "----------------------------------------------\n");
+
+       bool listed = FALSE;
+       for (int i = 0; i < MAX_BOUNTY; i++)
+       {
+               if (current_world_ptr->bounty_r_idx[i] <= 10000)
+               {
+                       fprintf(fff, "%s\n", r_name + r_info[current_world_ptr->bounty_r_idx[i]].name);
+                       listed = TRUE;
+               }
+       }
+
+       if (!listed)
+       {
+               fprintf(fff, "\n%s\n", _("賞金首はもう残っていません。", "There are no more wanted monster."));
+       }
+
+       my_fclose(fff);
+       (void)show_file(creature_ptr, TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
+       fd_kill(file_name);
+}
diff --git a/src/knowledge/knowledge-monsters.h b/src/knowledge/knowledge-monsters.h
new file mode 100644 (file)
index 0000000..0cc6fef
--- /dev/null
@@ -0,0 +1,6 @@
+#pragma once
+
+void do_cmd_knowledge_monsters(player_type *creature_ptr, bool *need_redraw, bool visual_only, IDX direct_r_idx);
+void do_cmd_knowledge_pets(player_type *creature_ptr);
+void do_cmd_knowledge_kill_count(player_type *creature_ptr);
+void do_cmd_knowledge_bounty(player_type *creature_ptr);