-/*!
+/*!
* @file status-first-page.c
- * @brief \83L\83\83\83\89\8aî\96{\8fî\95ñ\8by\82Ñ\8bZ\94\\92l\82Ì\95\\8e¦
+ * @brief キャラ基本情報及び技能値の表示
* @date 2020/02/23
* @author Hourier
*/
-#include "angband.h"
+#include "system/angband.h"
+#include "term/gameterm.h"
#include "status-first-page.h"
-#include "artifact.h"
+#include "display-util.h"
+#include "object/artifact.h"
#include "combat/melee.h"
#include "combat/shoot.h"
-#include "object-hook.h"
-#include "objectkind.h"
+#include "object/object-hook.h"
+#include "object/object-kind.h"
static TERM_COLOR likert_color = TERM_WHITE;
/*!
- * @brief \8bZ\94\\83\89\83\93\83N\82Ì\95\\8e¦\8aî\8f\80\82ð\92è\82ß\82é
+ * @brief
+ * @param creature_ptr プレーヤーへの参照ポインタ
+ * @param o_ptr 装備中の弓への参照ポインタ
+ * @param shots 射撃回数
+ * @param shot_frac 射撃速度
+ * @return なし
+ */
+static void calc_shot_params(player_type *creature_ptr, object_type *o_ptr, int *shots, int *shot_frac)
+{
+ if (o_ptr->k_idx == 0) return;
+
+ ENERGY energy_fire = bow_energy(o_ptr->sval);
+ *shots = creature_ptr->num_fire * 100;
+ *shot_frac = ((*shots) * 100 / energy_fire) % 100;
+ *shots = (*shots) / energy_fire;
+ if (o_ptr->name1 != ART_CRIMSON) return;
+
+ *shots = 1;
+ *shot_frac = 0;
+ if (creature_ptr->pclass != CLASS_ARCHER) return;
+
+ if (creature_ptr->lev >= 10) (*shots)++;
+ if (creature_ptr->lev >= 30) (*shots)++;
+ if (creature_ptr->lev >= 45) (*shots)++;
+}
+
+
+/*!
+ * @brief 武器装備に制限のあるクラスで、直接攻撃のダメージを計算する
+ * @param creature_ptr プレーヤーへの参照ポインタ
+ * @param hand 手 (利き手が0、反対の手が1…のはず)
+ * @param damage 直接攻撃のダメージ
+ * @param basedam 素手における直接攻撃のダメージ
+ * @param o_ptr 装備中の武器への参照ポインタ
+ * @return 利き手ならTRUE、反対の手ならFALSE
+ */
+static bool calc_weapon_damage_limit(player_type *creature_ptr, int hand, int *damage, int *basedam, object_type *o_ptr)
+{
+ PLAYER_LEVEL level = creature_ptr->lev;
+ if (hand > 0)
+ {
+ damage[hand] = 0;
+ return FALSE;
+ }
+
+ if (creature_ptr->pclass == CLASS_FORCETRAINER) level = MAX(1, level - 3);
+ if (creature_ptr->special_defense & KAMAE_BYAKKO)
+ *basedam = monk_ave_damage[level][1];
+ else if (creature_ptr->special_defense & (KAMAE_GENBU | KAMAE_SUZAKU))
+ *basedam = monk_ave_damage[level][2];
+ else
+ *basedam = monk_ave_damage[level][0];
+
+ damage[hand] += *basedam;
+ if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_POISON_NEEDLE)) damage[hand] = 1;
+ if (damage[hand] < 0) damage[hand] = 0;
+
+ return TRUE;
+}
+
+
+/*!
+ * @brief 片手あたりのダメージ量を計算する
+ * @param o_ptr 装備中の武器への参照ポインタ
+ * @param hand 手
+ * @param damage 直接攻撃のダメージ
+ * @param basedam 素手における直接攻撃のダメージ
+ * @return 素手ならFALSE、武器を持っていればTRUE
+ */
+static bool calc_weapon_one_hand(object_type *o_ptr, int hand, int *damage, int *basedam)
+{
+ if (o_ptr->k_idx == 0) return FALSE;
+
+ *basedam = 0;
+ damage[hand] += *basedam;
+ if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_POISON_NEEDLE))
+ damage[hand] = 1;
+
+ if (damage[hand] < 0)
+ damage[hand] = 0;
+
+ return TRUE;
+}
+
+
+/*!
+ * @brief ヴォーパル武器等によるダメージ強化
+ * @param creature_ptr プレーヤーへの参照ポインタ
+ * @param o_ptr 装備中の武器への参照ポインタ
+ * @param basedam 素手における直接攻撃のダメージ
+ * @param flgs オブジェクトフラグ群
+ * @return 強化後の素手ダメージ
+ */
+static int strengthen_basedam(player_type *creature_ptr, object_type *o_ptr, int basedam, BIT_FLAGS *flgs)
+{
+ if (OBJECT_IS_FULL_KNOWN(o_ptr) && ((o_ptr->name1 == ART_VORPAL_BLADE) || (o_ptr->name1 == ART_CHAINSWORD)))
+ {
+ /* vorpal blade */
+ basedam *= 5;
+ basedam /= 3;
+ }
+ else if (have_flag(flgs, TR_VORPAL))
+ {
+ /* vorpal flag only */
+ basedam *= 11;
+ basedam /= 9;
+ }
+
+ // 理力
+ bool is_force = creature_ptr->pclass != CLASS_SAMURAI;
+ is_force &= have_flag(flgs, TR_FORCE_WEAPON);
+ is_force &= creature_ptr->csp > (o_ptr->dd * o_ptr->ds / 5);
+ if (is_force) basedam = basedam * 7 / 2;
+
+ return basedam;
+}
+
+
+/*!
+ * @brief 技能ランクの表示基準を定める
* Returns a "rating" of x depending on y
- * @param x \8bZ\94\\92l
- * @param y \8bZ\94\\92l\82É\91Î\82·\82é\83\89\83\93\83N\8aî\8f\80\94ä
- * @return \82È\82µ
+ * @param x 技能値
+ * @param y 技能値に対するランク基準比
+ * @return なし
*/
static concptr likert(int x, int y)
{
if (x < 0)
{
likert_color = TERM_L_DARK;
- strcat(dummy, _("\8dÅ\92á", "Very Bad"));
+ strcat(dummy, _("最低", "Very Bad"));
return dummy;
}
case 1:
{
likert_color = TERM_RED;
- strcat(dummy, _("\88«\82¢", "Bad"));
+ strcat(dummy, _("悪い", "Bad"));
break;
}
case 2:
{
likert_color = TERM_L_RED;
- strcat(dummy, _("\97ò\82é", "Poor"));
+ strcat(dummy, _("劣る", "Poor"));
break;
}
case 3:
case 4:
{
likert_color = TERM_ORANGE;
- strcat(dummy, _("\95\81\92Ê", "Fair"));
+ strcat(dummy, _("普通", "Fair"));
break;
}
case 5:
{
likert_color = TERM_YELLOW;
- strcat(dummy, _("\97Ç\82¢", "Good"));
+ strcat(dummy, _("良い", "Good"));
break;
}
case 6:
{
likert_color = TERM_YELLOW;
- strcat(dummy, _("\91å\95Ï\97Ç\82¢", "Very Good"));
+ strcat(dummy, _("大変良い", "Very Good"));
break;
}
case 7:
case 8:
{
likert_color = TERM_L_GREEN;
- strcat(dummy, _("\91ì\89z", "Excellent"));
+ strcat(dummy, _("卓越", "Excellent"));
break;
}
case 9:
case 13:
{
likert_color = TERM_GREEN;
- strcat(dummy, _("\92´\89z", "Superb"));
+ strcat(dummy, _("超越", "Superb"));
break;
}
case 14:
case 17:
{
likert_color = TERM_BLUE;
- strcat(dummy, _("\89p\97Y\93I", "Heroic"));
+ strcat(dummy, _("英雄的", "Heroic"));
break;
}
default:
{
likert_color = TERM_VIOLET;
- sprintf(dummy2, _("\93`\90à\93I[%d]", "Legendary[%d]"), (int)((((x / y) - 17) * 5) / 2));
+ sprintf(dummy2, _("伝説的[%d]", "Legendary[%d]"), (int)((((x / y) - 17) * 5) / 2));
strcat(dummy, dummy2);
break;
}
/*!
- * @brief \83L\83\83\83\89\8aî\96{\8fî\95ñ\8by\82Ñ\8bZ\94\\92l\82ð\83\81\83C\83\93\83E\83B\83\93\83h\83E\82É\95\\8e¦\82·\82é
- * @param creature_ptr \83v\83\8c\81[\83\84\81[\82Ö\82Ì\8eQ\8fÆ\83|\83C\83\93\83^
- * @param xthb \95\90\8aí\93\99\82ð\8aÜ\82ß\82½\8dÅ\8fI\96½\92\86\97¦
- * @param damage \91Å\8c\82\8fC\90³
- * @param shots \8eË\8c\82\89ñ\90\94
- * @param shot_frac \8eË\8c\82\91¬\93x
- * @param display_player_one_line 1\8ds\95\\8e¦\97p\82Ì\83R\81[\83\8b\83o\83b\83N\8aÖ\90\94
- * @return \82È\82µ
+ * @brief 弓+両手の武器それぞれについてダメージを計算する
+ * @param creature_ptr プレーヤーへの参照ポインタ
+ * @param damage 直接攻撃のダメージ
+ * @param to_h 命中補正
+ * @return なし
+ */
+static void calc_two_hands(player_type *creature_ptr, int *damage, int *to_h)
+{
+ object_type *o_ptr;
+ o_ptr = &creature_ptr->inventory_list[INVEN_BOW];
+ BIT_FLAGS flgs[TR_FLAG_SIZE];
+ for (int i = 0; i < 2; i++)
+ {
+ int basedam;
+ damage[i] = creature_ptr->dis_to_d[i] * 100;
+ if (((creature_ptr->pclass == CLASS_MONK) || (creature_ptr->pclass == CLASS_FORCETRAINER)) && (empty_hands(creature_ptr, TRUE) & EMPTY_HAND_RARM))
+ {
+ if (!calc_weapon_damage_limit(creature_ptr, i, damage, &basedam, o_ptr))
+ break;
+
+ continue;
+ }
+
+ o_ptr = &creature_ptr->inventory_list[INVEN_RARM + i];
+ if (calc_weapon_one_hand(o_ptr, i, damage, &basedam)) continue;
+
+ to_h[i] = 0;
+ bool poison_needle = FALSE;
+ if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_POISON_NEEDLE)) poison_needle = TRUE;
+ if (object_is_known(o_ptr))
+ {
+ damage[i] += o_ptr->to_d * 100;
+ to_h[i] += o_ptr->to_h;
+ }
+
+ basedam = ((o_ptr->dd + creature_ptr->to_dd[i]) * (o_ptr->ds + creature_ptr->to_ds[i] + 1)) * 50;
+ object_flags_known(o_ptr, flgs);
+
+ basedam = calc_expect_crit(creature_ptr, o_ptr->weight, to_h[i], basedam, creature_ptr->dis_to_h[i], poison_needle);
+ basedam = strengthen_basedam(creature_ptr, o_ptr, basedam, flgs);
+ damage[i] += basedam;
+ if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_POISON_NEEDLE)) damage[i] = 1;
+ if (damage[i] < 0) damage[i] = 0;
+ }
+}
+
+
+/*!
+ * @brief キャラ基本情報及び技能値をメインウィンドウに表示する
+ * @param creature_ptr プレーヤーへの参照ポインタ
+ * @param xthb 武器等を含めた最終命中率
+ * @param damage 打撃修正
+ * @param shots 射撃回数
+ * @param shot_frac 射撃速度
+ * @param display_player_one_line 1行表示用のコールバック関数
+ * @return なし
*/
-static void display_first_page(player_type *creature_ptr, int xthb, int *damage, int shots, int shot_frac, void(*display_player_one_line)(int, concptr, TERM_COLOR))
+static void display_first_page(player_type *creature_ptr, int xthb, int *damage, int shots, int shot_frac)
{
int xthn = creature_ptr->skill_thn + (creature_ptr->to_h_m * BTH_PLUS_ADJ);
int xdig = creature_ptr->skill_dig;
concptr desc = likert(xthn, 12);
- (*display_player_one_line)(ENTRY_SKILL_FIGHT, desc, likert_color);
+ display_player_one_line(ENTRY_SKILL_FIGHT, desc, likert_color);
desc = likert(xthb, 12);
- (*display_player_one_line)(ENTRY_SKILL_SHOOT, desc, likert_color);
+ display_player_one_line(ENTRY_SKILL_SHOOT, desc, likert_color);
desc = likert(xsav, 7);
- (*display_player_one_line)(ENTRY_SKILL_SAVING, desc, likert_color);
+ display_player_one_line(ENTRY_SKILL_SAVING, desc, likert_color);
desc = likert((xstl > 0) ? xstl : -1, 1);
- (*display_player_one_line)(ENTRY_SKILL_STEALTH, desc, likert_color);
+ display_player_one_line(ENTRY_SKILL_STEALTH, desc, likert_color);
desc = likert(xfos, 6);
- (*display_player_one_line)(ENTRY_SKILL_PERCEP, desc, likert_color);
+ display_player_one_line(ENTRY_SKILL_PERCEP, desc, likert_color);
desc = likert(xsrh, 6);
- (*display_player_one_line)(ENTRY_SKILL_SEARCH, desc, likert_color);
+ display_player_one_line(ENTRY_SKILL_SEARCH, desc, likert_color);
desc = likert(xdis, 8);
- (*display_player_one_line)(ENTRY_SKILL_DISARM, desc, likert_color);
+ display_player_one_line(ENTRY_SKILL_DISARM, desc, likert_color);
desc = likert(xdev, 6);
- (*display_player_one_line)(ENTRY_SKILL_DEVICE, desc, likert_color);
+ display_player_one_line(ENTRY_SKILL_DEVICE, desc, likert_color);
desc = likert(xdev, 6);
- (*display_player_one_line)(ENTRY_SKILL_DEVICE, desc, likert_color);
+ display_player_one_line(ENTRY_SKILL_DEVICE, desc, likert_color);
desc = likert(xdig, 4);
- (*display_player_one_line)(ENTRY_SKILL_DIG, desc, likert_color);
+ display_player_one_line(ENTRY_SKILL_DIG, desc, likert_color);
if (!muta_att)
- (*display_player_one_line)(ENTRY_BLOWS, format("%d+%d", blows1, blows2), TERM_L_BLUE);
+ display_player_one_line(ENTRY_BLOWS, format("%d+%d", blows1, blows2), TERM_L_BLUE);
else
- (*display_player_one_line)(ENTRY_BLOWS, format("%d+%d+%d", blows1, blows2, muta_att), TERM_L_BLUE);
+ display_player_one_line(ENTRY_BLOWS, format("%d+%d+%d", blows1, blows2, muta_att), TERM_L_BLUE);
- (*display_player_one_line)(ENTRY_SHOTS, format("%d.%02d", shots, shot_frac), TERM_L_BLUE);
+ display_player_one_line(ENTRY_SHOTS, format("%d.%02d", shots, shot_frac), TERM_L_BLUE);
if ((damage[0] + damage[1]) == 0)
desc = "nil!";
else
desc = format("%d+%d", blows1 * damage[0] / 100, blows2 * damage[1] / 100);
- (*display_player_one_line)(ENTRY_AVG_DMG, desc, TERM_L_BLUE);
- (*display_player_one_line)(ENTRY_INFRA, format("%d feet", creature_ptr->see_infra * 10), TERM_WHITE);
+ display_player_one_line(ENTRY_AVG_DMG, desc, TERM_L_BLUE);
+ display_player_one_line(ENTRY_INFRA, format("%d feet", creature_ptr->see_infra * 10), TERM_WHITE);
}
/*!
- * @brief \83v\83\8c\83C\83\84\81[\83X\83e\81[\83^\83X\82Ì1\83y\81[\83W\96Ú\8ae\8eí\8fÚ\8d×\82ð\82Ü\82Æ\82ß\82Ä\95\\8e¦\82·\82é
+ * @brief プレイヤーステータスの1ページ目各種詳細をまとめて表示する
* Prints ratings on certain abilities
- * @param creature_ptr \83v\83\8c\81[\83\84\81[\82Ö\82Ì\8eQ\8fÆ\83|\83C\83\93\83^
- * @param display_player_one_line 1\8ds\95\\8e¦\97p\82Ì\83R\81[\83\8b\83o\83b\83N\8aÖ\90\94
- * @return \82È\82µ
+ * @param creature_ptr プレーヤーへの参照ポインタ
+ * @param display_player_one_line 1行表示用のコールバック関数
+ * @return なし
* @details
* This code is "imitated" elsewhere to "dump" a character sheet.
*/
-void display_player_various(player_type *creature_ptr, void(*display_player_one_line)(int, concptr, TERM_COLOR))
+void display_player_various(player_type *creature_ptr)
{
object_type *o_ptr;
o_ptr = &creature_ptr->inventory_list[INVEN_BOW];
int xthb = creature_ptr->skill_thb + (tmp * BTH_PLUS_ADJ);
int shots = 0;
int shot_frac = 0;
- if (o_ptr->k_idx > 0)
- {
- ENERGY energy_fire = bow_energy(o_ptr->sval);
- shots = creature_ptr->num_fire * 100;
- shot_frac = (shots * 100 / energy_fire) % 100;
- shots = shots / energy_fire;
- if (o_ptr->name1 == ART_CRIMSON)
- {
- shots = 1;
- shot_frac = 0;
- if (creature_ptr->pclass == CLASS_ARCHER)
- {
- if (creature_ptr->lev >= 10) shots++;
- if (creature_ptr->lev >= 30) shots++;
- if (creature_ptr->lev >= 45) shots++;
- }
- }
- }
+ calc_shot_params(creature_ptr, o_ptr, &shots, &shot_frac);
int damage[2];
int to_h[2];
- int basedam;
- BIT_FLAGS flgs[TR_FLAG_SIZE];
- for (int i = 0; i < 2; i++)
- {
- damage[i] = creature_ptr->dis_to_d[i] * 100;
- if (((creature_ptr->pclass == CLASS_MONK) || (creature_ptr->pclass == CLASS_FORCETRAINER)) && (empty_hands(creature_ptr, TRUE) & EMPTY_HAND_RARM))
- {
- PLAYER_LEVEL level = creature_ptr->lev;
- if (i > 0)
- {
- damage[i] = 0;
- break;
- }
-
- if (creature_ptr->pclass == CLASS_FORCETRAINER) level = MAX(1, level - 3);
- if (creature_ptr->special_defense & KAMAE_BYAKKO)
- basedam = monk_ave_damage[level][1];
- else if (creature_ptr->special_defense & (KAMAE_GENBU | KAMAE_SUZAKU))
- basedam = monk_ave_damage[level][2];
- else
- basedam = monk_ave_damage[level][0];
-
- damage[i] += basedam;
- if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_POISON_NEEDLE)) damage[i] = 1;
- if (damage[i] < 0) damage[i] = 0;
- continue;
- }
-
- o_ptr = &creature_ptr->inventory_list[INVEN_RARM + i];
- if (o_ptr->k_idx == 0)
- {
- basedam = 0;
- damage[i] += basedam;
- if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_POISON_NEEDLE)) damage[i] = 1;
- if (damage[i] < 0) damage[i] = 0;
- continue;
- }
-
- to_h[i] = 0;
- bool poison_needle = FALSE;
- if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_POISON_NEEDLE)) poison_needle = TRUE;
- if (object_is_known(o_ptr))
- {
- damage[i] += o_ptr->to_d * 100;
- to_h[i] += o_ptr->to_h;
- }
-
- basedam = ((o_ptr->dd + creature_ptr->to_dd[i]) * (o_ptr->ds + creature_ptr->to_ds[i] + 1)) * 50;
- object_flags_known(o_ptr, flgs);
-
- basedam = calc_expect_crit(creature_ptr, o_ptr->weight, to_h[i], basedam, creature_ptr->dis_to_h[i], poison_needle);
- if (OBJECT_IS_FULL_KNOWN(o_ptr) && ((o_ptr->name1 == ART_VORPAL_BLADE) || (o_ptr->name1 == ART_CHAINSWORD)))
- {
- /* vorpal blade */
- basedam *= 5;
- basedam /= 3;
- }
- else if (have_flag(flgs, TR_VORPAL))
- {
- /* vorpal flag only */
- basedam *= 11;
- basedam /= 9;
- }
-
- if ((creature_ptr->pclass != CLASS_SAMURAI) && have_flag(flgs, TR_FORCE_WEAPON) && (creature_ptr->csp > (o_ptr->dd * o_ptr->ds / 5)))
- basedam = basedam * 7 / 2;
-
- damage[i] += basedam;
- if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_POISON_NEEDLE)) damage[i] = 1;
- if (damage[i] < 0) damage[i] = 0;
- }
-
- display_first_page(creature_ptr, xthb, damage, shots, shot_frac, display_player_one_line);
+ calc_two_hands(creature_ptr, damage, to_h);
+ display_first_page(creature_ptr, xthb, damage, shots, shot_frac);
}