OSDN Git Service

Merge pull request #3532 from sikabane-works/release/3.0.0.87-alpha
[hengbandforosx/hengbandosx.git] / src / melee / melee-switcher.cpp
1 /*!
2  * @brief モンスター同士が乱闘を起こした時の攻撃種別をスイッチングする
3  * @date 2020/05/30
4  * @author Hourier
5  */
6
7 #include "melee/melee-switcher.h"
8 #include "core/disturbance.h"
9 #include "melee/melee-util.h"
10 #include "monster-attack/monster-attack-effect.h"
11 #include "monster/monster-status-setter.h"
12 #include "spell-kind/earthquake.h"
13 #include "system/monster-entity.h"
14 #include "system/player-type-definition.h"
15 #include "view/display-messages.h"
16
17 void describe_melee_method(PlayerType *player_ptr, mam_type *mam_ptr)
18 {
19     switch (mam_ptr->method) {
20     case RaceBlowMethodType::HIT: {
21         mam_ptr->act = _("%sを殴った。", "hits %s.");
22         mam_ptr->touched = true;
23         break;
24     }
25     case RaceBlowMethodType::TOUCH: {
26         mam_ptr->act = _("%sを触った。", "touches %s.");
27         mam_ptr->touched = true;
28         break;
29     }
30     case RaceBlowMethodType::PUNCH: {
31         mam_ptr->act = _("%sをパンチした。", "punches %s.");
32         mam_ptr->touched = true;
33         break;
34     }
35     case RaceBlowMethodType::KICK: {
36         mam_ptr->act = _("%sを蹴った。", "kicks %s.");
37         mam_ptr->touched = true;
38         break;
39     }
40     case RaceBlowMethodType::CLAW: {
41         mam_ptr->act = _("%sをひっかいた。", "claws %s.");
42         mam_ptr->touched = true;
43         break;
44     }
45     case RaceBlowMethodType::BITE: {
46         mam_ptr->act = _("%sを噛んだ。", "bites %s.");
47         mam_ptr->touched = true;
48         break;
49     }
50     case RaceBlowMethodType::STING: {
51         mam_ptr->act = _("%sを刺した。", "stings %s.");
52         mam_ptr->touched = true;
53         break;
54     }
55     case RaceBlowMethodType::SLASH: {
56         mam_ptr->act = _("%sを斬った。", "slashes %s.");
57         break;
58     }
59     case RaceBlowMethodType::BUTT: {
60         mam_ptr->act = _("%sを角で突いた。", "butts %s.");
61         mam_ptr->touched = true;
62         break;
63     }
64     case RaceBlowMethodType::CRUSH: {
65         mam_ptr->act = _("%sに体当りした。", "crushes %s.");
66         mam_ptr->touched = true;
67         break;
68     }
69     case RaceBlowMethodType::ENGULF: {
70         mam_ptr->act = _("%sを飲み込んだ。", "engulfs %s.");
71         mam_ptr->touched = true;
72         break;
73     }
74     case RaceBlowMethodType::CHARGE: {
75         mam_ptr->act = _("%sに請求書をよこした。", "charges %s.");
76         mam_ptr->touched = true;
77         break;
78     }
79     case RaceBlowMethodType::CRAWL: {
80         mam_ptr->act = _("%sの体の上を這い回った。", "crawls on %s.");
81         mam_ptr->touched = true;
82         break;
83     }
84     case RaceBlowMethodType::DROOL: {
85         mam_ptr->act = _("%sによだれをたらした。", "drools on %s.");
86         mam_ptr->touched = false;
87         break;
88     }
89     case RaceBlowMethodType::SPIT: {
90         mam_ptr->act = _("%sに唾を吐いた。", "spits on %s.");
91         mam_ptr->touched = false;
92         break;
93     }
94     case RaceBlowMethodType::EXPLODE: {
95         if (mam_ptr->see_either) {
96             disturb(player_ptr, true, true);
97         }
98
99         mam_ptr->act = _("爆発した。", "explodes.");
100         mam_ptr->explode = true;
101         mam_ptr->touched = false;
102         break;
103     }
104     case RaceBlowMethodType::GAZE: {
105         mam_ptr->act = _("%sをにらんだ。", "gazes at %s.");
106         mam_ptr->touched = false;
107         break;
108     }
109     case RaceBlowMethodType::WAIL: {
110         mam_ptr->act = _("%sに泣きついた。", "wails at %s.");
111         mam_ptr->touched = false;
112         break;
113     }
114     case RaceBlowMethodType::SPORE: {
115         mam_ptr->act = _("%sに胞子を飛ばした。", "releases spores at %s.");
116         mam_ptr->touched = false;
117         break;
118     }
119     case RaceBlowMethodType::XXX4: {
120         mam_ptr->act = _("%sにXXX4を飛ばした。", "projects XXX4's at %s.");
121         mam_ptr->touched = false;
122         break;
123     }
124     case RaceBlowMethodType::BEG: {
125         mam_ptr->act = _("%sに金をせがんだ。", "begs %s for money.");
126         mam_ptr->touched = false;
127         break;
128     }
129     case RaceBlowMethodType::INSULT: {
130         mam_ptr->act = _("%sを侮辱した。", "insults %s.");
131         mam_ptr->touched = false;
132         break;
133     }
134     case RaceBlowMethodType::MOAN: {
135         mam_ptr->act = _("%sにむかってうめいた。", "moans at %s.");
136         mam_ptr->touched = false;
137         break;
138     }
139     case RaceBlowMethodType::SHOW: {
140         mam_ptr->act = _("%sにむかって歌った。", "sings to %s.");
141         mam_ptr->touched = false;
142         break;
143     }
144
145     case RaceBlowMethodType::NONE:
146     case RaceBlowMethodType::SHOOT:
147     case RaceBlowMethodType::MAX:
148         break;
149     }
150 }
151
152 void decide_monster_attack_effect(PlayerType *player_ptr, mam_type *mam_ptr)
153 {
154     switch (mam_ptr->effect) {
155     case RaceBlowEffectType::NONE:
156     case RaceBlowEffectType::DR_MANA:
157         mam_ptr->damage = 0;
158         mam_ptr->pt = AttributeType::NONE;
159         break;
160     case RaceBlowEffectType::SUPERHURT:
161         if ((randint1(mam_ptr->rlev * 2 + 250) > (mam_ptr->ac + 200)) || one_in_(13)) {
162             int tmp_damage = mam_ptr->damage - (mam_ptr->damage * ((mam_ptr->ac < 150) ? mam_ptr->ac : 150) / 250);
163             mam_ptr->damage = std::max(mam_ptr->damage, tmp_damage * 2);
164             break;
165         }
166
167         [[fallthrough]];
168     case RaceBlowEffectType::HURT:
169         mam_ptr->damage -= (mam_ptr->damage * ((mam_ptr->ac < 150) ? mam_ptr->ac : 150) / 250);
170         break;
171     case RaceBlowEffectType::POISON:
172     case RaceBlowEffectType::DISEASE:
173         mam_ptr->pt = AttributeType::POIS;
174         break;
175     case RaceBlowEffectType::UN_BONUS:
176     case RaceBlowEffectType::UN_POWER:
177         mam_ptr->pt = AttributeType::DISENCHANT;
178         break;
179     case RaceBlowEffectType::EAT_ITEM:
180     case RaceBlowEffectType::EAT_GOLD:
181         if ((player_ptr->riding != mam_ptr->m_idx) && one_in_(2)) {
182             mam_ptr->blinked = true;
183         }
184
185         break;
186     case RaceBlowEffectType::EAT_FOOD:
187     case RaceBlowEffectType::EAT_LITE:
188     case RaceBlowEffectType::BLIND:
189     case RaceBlowEffectType::LOSE_STR:
190     case RaceBlowEffectType::LOSE_INT:
191     case RaceBlowEffectType::LOSE_WIS:
192     case RaceBlowEffectType::LOSE_DEX:
193     case RaceBlowEffectType::LOSE_CON:
194     case RaceBlowEffectType::LOSE_CHR:
195     case RaceBlowEffectType::LOSE_ALL:
196         break;
197     case RaceBlowEffectType::ACID:
198         mam_ptr->pt = AttributeType::ACID;
199         break;
200     case RaceBlowEffectType::ELEC:
201         mam_ptr->pt = AttributeType::ELEC;
202         break;
203     case RaceBlowEffectType::FIRE:
204         mam_ptr->pt = AttributeType::FIRE;
205         break;
206     case RaceBlowEffectType::COLD:
207         mam_ptr->pt = AttributeType::COLD;
208         break;
209     case RaceBlowEffectType::CONFUSE:
210         mam_ptr->pt = AttributeType::CONFUSION;
211         break;
212     case RaceBlowEffectType::TERRIFY:
213         mam_ptr->attribute = BlowEffectType::FEAR;
214         break;
215     case RaceBlowEffectType::PARALYZE:
216         mam_ptr->attribute = BlowEffectType::SLEEP;
217         break;
218     case RaceBlowEffectType::SHATTER:
219         mam_ptr->damage -= (mam_ptr->damage * ((mam_ptr->ac < 150) ? mam_ptr->ac : 150) / 250);
220         if (mam_ptr->damage > 23) {
221             earthquake(player_ptr, mam_ptr->m_ptr->fy, mam_ptr->m_ptr->fx, 8, mam_ptr->m_idx);
222         }
223
224         break;
225     case RaceBlowEffectType::EXP_10:
226     case RaceBlowEffectType::EXP_20:
227     case RaceBlowEffectType::EXP_40:
228     case RaceBlowEffectType::EXP_80:
229         mam_ptr->pt = AttributeType::NETHER;
230         break;
231     case RaceBlowEffectType::TIME:
232         mam_ptr->pt = AttributeType::TIME;
233         break;
234     case RaceBlowEffectType::DR_LIFE:
235         mam_ptr->pt = AttributeType::HYPODYNAMIA;
236         mam_ptr->attribute = BlowEffectType::HEAL;
237         break;
238     case RaceBlowEffectType::INERTIA:
239         mam_ptr->pt = AttributeType::INERTIAL;
240         break;
241     case RaceBlowEffectType::STUN:
242         mam_ptr->pt = AttributeType::SOUND;
243         break;
244     case RaceBlowEffectType::HUNGRY:
245         mam_ptr->pt = AttributeType::HUNGRY;
246         break;
247     case RaceBlowEffectType::FLAVOR:
248         // フレーバー打撃には何の効果もない。
249         mam_ptr->pt = AttributeType::NONE;
250         break;
251     default:
252         mam_ptr->pt = AttributeType::NONE;
253         break;
254     }
255 }
256
257 void describe_monster_missed_monster(PlayerType *player_ptr, mam_type *mam_ptr)
258 {
259     switch (mam_ptr->method) {
260     case RaceBlowMethodType::HIT:
261     case RaceBlowMethodType::TOUCH:
262     case RaceBlowMethodType::PUNCH:
263     case RaceBlowMethodType::KICK:
264     case RaceBlowMethodType::CLAW:
265     case RaceBlowMethodType::BITE:
266     case RaceBlowMethodType::STING:
267     case RaceBlowMethodType::SLASH:
268     case RaceBlowMethodType::BUTT:
269     case RaceBlowMethodType::CRUSH:
270     case RaceBlowMethodType::ENGULF:
271     case RaceBlowMethodType::CHARGE: {
272         (void)set_monster_csleep(player_ptr, mam_ptr->t_idx, 0);
273         if (mam_ptr->see_m) {
274 #ifdef JP
275             msg_format("%sは%s^の攻撃をかわした。", mam_ptr->t_name, mam_ptr->m_name);
276 #else
277             msg_format("%s^ misses %s.", mam_ptr->m_name, mam_ptr->t_name);
278 #endif
279         }
280
281         return;
282     }
283     default:
284         return;
285     }
286 }