OSDN Git Service

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