OSDN Git Service

[Refactor] #40014 Separated lore-calculator.c/h from monster-lore.c/h
[hengband/hengband.git] / src / lore / lore-calculator.c
1 #include "lore/lore-calculator.h"
2 #include "monster-race/race-flags1.h"
3 #include "mspell/monster-spell.h"
4 #include "mspell/mspell-damage-calculator.h"
5
6 /*!
7  * @brief ダイス目を文字列に変換する
8  * @param base_damage 固定値
9  * @param dice_num ダイス数
10  * @param dice_side ダイス面
11  * @param dice_mult ダイス倍率
12  * @param dice_div ダイス除数
13  * @param msg 文字列を格納するポインタ
14  * @return なし
15  */
16 void dice_to_string(int base_damage, int dice_num, int dice_side, int dice_mult, int dice_div, char *msg)
17 {
18     char base[80] = "", dice[80] = "", mult[80] = "";
19
20     if (dice_num == 0) {
21         sprintf(msg, "%d", base_damage);
22         return;
23     }
24
25     if (base_damage != 0)
26         sprintf(base, "%d+", base_damage);
27
28     if (dice_num == 1)
29         sprintf(dice, "d%d", dice_side);
30     else
31         sprintf(dice, "%dd%d", dice_num, dice_side);
32
33     if (dice_mult != 1 || dice_div != 1) {
34         if (dice_div == 1)
35             sprintf(mult, "*%d", dice_mult);
36         else
37             sprintf(mult, "*(%d/%d)", dice_mult, dice_div);
38     }
39
40     sprintf(msg, "%s%s%s", base, dice, mult);
41 }
42
43 /*!
44  * @brief モンスターのAC情報を得ることができるかを返す / Determine if the "armor" is known
45  * @param r_idx モンスターの種族ID
46  * @return 敵のACを知る条件が満たされているならTRUEを返す
47  * @details
48  * The higher the level, the fewer kills needed.
49  */
50 bool know_armour(MONRACE_IDX r_idx)
51 {
52     monster_race *r_ptr = &r_info[r_idx];
53     DEPTH level = r_ptr->level;
54     MONSTER_NUMBER kills = r_ptr->r_tkills;
55
56     bool known = (r_ptr->r_cast_spell == MAX_UCHAR) ? TRUE : FALSE;
57
58     if (cheat_know || known)
59         return TRUE;
60     if (kills > 304 / (4 + level))
61         return TRUE;
62     if (!(r_ptr->flags1 & RF1_UNIQUE))
63         return FALSE;
64     if (kills > 304 / (38 + (5 * level) / 4))
65         return TRUE;
66     return FALSE;
67 }
68
69 /*!
70  * @brief モンスターの打撃威力を知ることができるかどうかを返す
71  * Determine if the "damage" of the given attack is known
72  * @param r_idx モンスターの種族ID
73  * @param i 確認したい攻撃手番
74  * @return 敵のダメージダイスを知る条件が満たされているならTRUEを返す
75  * @details
76  * <pre>
77  * the higher the level of the monster, the fewer the attacks you need,
78  * the more damage an attack does, the more attacks you need
79  * </pre>
80  */
81 bool know_damage(MONRACE_IDX r_idx, int i)
82 {
83     monster_race *r_ptr = &r_info[r_idx];
84     DEPTH level = r_ptr->level;
85     s32b a = r_ptr->r_blows[i];
86
87     s32b d1 = r_ptr->blow[i].d_dice;
88     s32b d2 = r_ptr->blow[i].d_side;
89     s32b d = d1 * d2;
90
91     if (d >= ((4 + level) * MAX_UCHAR) / 80)
92         d = ((4 + level) * MAX_UCHAR - 1) / 80;
93     if ((4 + level) * a > 80 * d)
94         return TRUE;
95     if (!(r_ptr->flags1 & RF1_UNIQUE))
96         return FALSE;
97     if ((4 + level) * (2 * a) > 80 * d)
98         return TRUE;
99
100     return FALSE;
101 }
102
103 /*!
104  * @brief 文字列にモンスターの攻撃力を加える
105  * @param r_idx モンスターの種族ID
106  * @param SPELL_NUM 呪文番号
107  * @param msg 表示する文字列
108  * @param tmp 返すメッセージを格納する配列
109  * @return なし
110  */
111 void set_damage(player_type *player_ptr, MONRACE_IDX r_idx, monster_spell_type ms_type, char *msg, char *tmp)
112 {
113     int base_damage = monspell_race_damage(player_ptr, ms_type, r_idx, BASE_DAM);
114     int dice_num = monspell_race_damage(player_ptr, ms_type, r_idx, DICE_NUM);
115     int dice_side = monspell_race_damage(player_ptr, ms_type, r_idx, DICE_SIDE);
116     int dice_mult = monspell_race_damage(player_ptr, ms_type, r_idx, DICE_MULT);
117     int dice_div = monspell_race_damage(player_ptr, ms_type, r_idx, DICE_DIV);
118     char dmg_str[80], dice_str[80];
119     dice_to_string(base_damage, dice_num, dice_side, dice_mult, dice_div, dmg_str);
120     sprintf(dice_str, "(%s)", dmg_str);
121
122     if (know_armour(r_idx))
123         sprintf(tmp, msg, dice_str);
124     else
125         sprintf(tmp, msg, "");
126 }
127
128 void set_drop_flags(lore_type *lore_ptr)
129 {
130     if (!lore_ptr->know_everything)
131         return;
132
133     lore_ptr->drop_gold = lore_ptr->drop_item = (((lore_ptr->r_ptr->flags1 & RF1_DROP_4D2) ? 8 : 0) + ((lore_ptr->r_ptr->flags1 & RF1_DROP_3D2) ? 6 : 0)
134         + ((lore_ptr->r_ptr->flags1 & RF1_DROP_2D2) ? 4 : 0) + ((lore_ptr->r_ptr->flags1 & RF1_DROP_1D2) ? 2 : 0)
135         + ((lore_ptr->r_ptr->flags1 & RF1_DROP_90) ? 1 : 0) + ((lore_ptr->r_ptr->flags1 & RF1_DROP_60) ? 1 : 0));
136
137     if (lore_ptr->r_ptr->flags1 & RF1_ONLY_GOLD)
138         lore_ptr->drop_item = 0;
139
140     if (lore_ptr->r_ptr->flags1 & RF1_ONLY_ITEM)
141         lore_ptr->drop_gold = 0;
142
143     lore_ptr->flags1 = lore_ptr->r_ptr->flags1;
144     lore_ptr->flags2 = lore_ptr->r_ptr->flags2;
145     lore_ptr->flags3 = lore_ptr->r_ptr->flags3;
146     lore_ptr->flags4 = lore_ptr->r_ptr->flags4;
147     lore_ptr->a_ability_flags1 = lore_ptr->r_ptr->a_ability_flags1;
148     lore_ptr->a_ability_flags2 = lore_ptr->r_ptr->a_ability_flags2;
149     lore_ptr->flagsr = lore_ptr->r_ptr->flagsr;
150 }