OSDN Git Service

7b013a5ef2332b63dde5db7a541518b6612cf2ea
[hengband/hengband.git] / src / effect / effect-monster-charm.c
1 #include "effect/effect-monster-charm.h"
2 #include "dungeon/quest.h"
3 #include "effect/effect-monster-util.h"
4 #include "effect/spells-effect-util.h"
5 #include "monster-race/monster-race-hook.h"
6 #include "monster-race/monster-race.h"
7 #include "monster-race/race-flags1.h"
8 #include "monster-race/race-flags3.h"
9 #include "monster-race/race-flags7.h"
10 #include "monster-race/race-indice-types.h"
11 #include "monster/monster-flag-types.h"
12 #include "monster/monster-info.h"
13 #include "monster/monster-list.h"
14 #include "monster-floor/monster-remover.h"
15 #include "monster/monster-status-setter.h"
16 #include "monster/monster-status.h"
17 #include "object-enchant/trc-types.h"
18 #include "pet/pet-fall-off.h"
19 #include "player-info/avatar.h"
20 #include "player/player-status-flags.h"
21 #include "status/bad-status-setter.h"
22 #include "spell/spells-diceroll.h"
23 #include "system/floor-type-definition.h"
24 #include "view/display-messages.h"
25
26 static void effect_monster_charm_resist(player_type *caster_ptr, effect_monster_type *em_ptr)
27 {
28     if (common_saving_throw_charm(caster_ptr, em_ptr->dam, em_ptr->m_ptr)) {
29         em_ptr->note = _("には効果がなかった。", " is unaffected.");
30         em_ptr->obvious = FALSE;
31
32         if (one_in_(4))
33             em_ptr->m_ptr->mflag2 |= MFLAG2_NOPET;
34     } else if (has_aggravate(caster_ptr)) {
35         em_ptr->note = _("はあなたに敵意を抱いている!", " hates you too much!");
36         if (one_in_(4))
37             em_ptr->m_ptr->mflag2 |= MFLAG2_NOPET;
38     } else {
39         em_ptr->note = _("は突然友好的になったようだ!", " suddenly seems friendly!");
40         set_pet(caster_ptr, em_ptr->m_ptr);
41
42         chg_virtue(caster_ptr, V_INDIVIDUALISM, -1);
43         if (em_ptr->r_ptr->flags3 & RF3_ANIMAL)
44             chg_virtue(caster_ptr, V_NATURE, 1);
45     }
46 }
47
48 process_result effect_monster_charm(player_type *caster_ptr, effect_monster_type *em_ptr)
49 {
50     int vir = virtue_number(caster_ptr, V_HARMONY);
51     if (vir) {
52         em_ptr->dam += caster_ptr->virtues[vir - 1] / 10;
53     }
54
55     vir = virtue_number(caster_ptr, V_INDIVIDUALISM);
56     if (vir) {
57         em_ptr->dam -= caster_ptr->virtues[vir - 1] / 20;
58     }
59
60     if (em_ptr->seen)
61         em_ptr->obvious = TRUE;
62
63     effect_monster_charm_resist(caster_ptr, em_ptr);
64     em_ptr->dam = 0;
65     return PROCESS_CONTINUE;
66 }
67
68 process_result effect_monster_control_undead(player_type *caster_ptr, effect_monster_type *em_ptr)
69 {
70     if (em_ptr->seen)
71         em_ptr->obvious = TRUE;
72
73     int vir = virtue_number(caster_ptr, V_UNLIFE);
74     if (vir) {
75         em_ptr->dam += caster_ptr->virtues[vir - 1] / 10;
76     }
77
78     vir = virtue_number(caster_ptr, V_INDIVIDUALISM);
79     if (vir) {
80         em_ptr->dam -= caster_ptr->virtues[vir - 1] / 20;
81     }
82
83     if (common_saving_throw_control(caster_ptr, em_ptr->dam, em_ptr->m_ptr) || !(em_ptr->r_ptr->flags3 & RF3_UNDEAD)) {
84         em_ptr->note = _("には効果がなかった。", " is unaffected.");
85         em_ptr->obvious = FALSE;
86         if (one_in_(4))
87             em_ptr->m_ptr->mflag2 |= MFLAG2_NOPET;
88     } else if (has_aggravate(caster_ptr)) {
89         em_ptr->note = _("はあなたに敵意を抱いている!", " hates you too much!");
90         if (one_in_(4))
91             em_ptr->m_ptr->mflag2 |= MFLAG2_NOPET;
92     } else {
93         em_ptr->note = _("は既にあなたの奴隷だ!", " is in your thrall!");
94         set_pet(caster_ptr, em_ptr->m_ptr);
95     }
96
97     em_ptr->dam = 0;
98     return PROCESS_CONTINUE;
99 }
100
101 process_result effect_monster_control_demon(player_type *caster_ptr, effect_monster_type *em_ptr)
102 {
103     if (em_ptr->seen)
104         em_ptr->obvious = TRUE;
105
106     int vir = virtue_number(caster_ptr, V_UNLIFE);
107     if (vir) {
108         em_ptr->dam += caster_ptr->virtues[vir - 1] / 10;
109     }
110
111     vir = virtue_number(caster_ptr, V_INDIVIDUALISM);
112     if (vir) {
113         em_ptr->dam -= caster_ptr->virtues[vir - 1] / 20;
114     }
115
116     if (common_saving_throw_control(caster_ptr, em_ptr->dam, em_ptr->m_ptr) || !(em_ptr->r_ptr->flags3 & RF3_DEMON)) {
117         em_ptr->note = _("には効果がなかった。", " is unaffected.");
118         em_ptr->obvious = FALSE;
119         if (one_in_(4))
120             em_ptr->m_ptr->mflag2 |= MFLAG2_NOPET;
121     } else if (has_aggravate(caster_ptr)) {
122         em_ptr->note = _("はあなたに敵意を抱いている!", " hates you too much!");
123         if (one_in_(4))
124             em_ptr->m_ptr->mflag2 |= MFLAG2_NOPET;
125     } else {
126         em_ptr->note = _("は既にあなたの奴隷だ!", " is in your thrall!");
127         set_pet(caster_ptr, em_ptr->m_ptr);
128     }
129
130     em_ptr->dam = 0;
131     return PROCESS_CONTINUE;
132 }
133
134 process_result effect_monster_control_animal(player_type *caster_ptr, effect_monster_type *em_ptr)
135 {
136     if (em_ptr->seen)
137         em_ptr->obvious = TRUE;
138
139     int vir = virtue_number(caster_ptr, V_NATURE);
140     if (vir) {
141         em_ptr->dam += caster_ptr->virtues[vir - 1] / 10;
142     }
143
144     vir = virtue_number(caster_ptr, V_INDIVIDUALISM);
145     if (vir) {
146         em_ptr->dam -= caster_ptr->virtues[vir - 1] / 20;
147     }
148
149     if (common_saving_throw_control(caster_ptr, em_ptr->dam, em_ptr->m_ptr) || !(em_ptr->r_ptr->flags3 & RF3_ANIMAL)) {
150         em_ptr->note = _("には効果がなかった。", " is unaffected.");
151         em_ptr->obvious = FALSE;
152         if (one_in_(4))
153             em_ptr->m_ptr->mflag2 |= MFLAG2_NOPET;
154     } else if (has_aggravate(caster_ptr)) {
155         em_ptr->note = _("はあなたに敵意を抱いている!", " hates you too much!");
156         if (one_in_(4))
157             em_ptr->m_ptr->mflag2 |= MFLAG2_NOPET;
158     } else {
159         em_ptr->note = _("はなついた。", " is tamed!");
160         set_pet(caster_ptr, em_ptr->m_ptr);
161         if (em_ptr->r_ptr->flags3 & RF3_ANIMAL)
162             chg_virtue(caster_ptr, V_NATURE, 1);
163     }
164
165     em_ptr->dam = 0;
166     return PROCESS_CONTINUE;
167 }
168
169 process_result effect_monster_charm_living(player_type *caster_ptr, effect_monster_type *em_ptr)
170 {
171     int vir = virtue_number(caster_ptr, V_UNLIFE);
172     if (em_ptr->seen)
173         em_ptr->obvious = TRUE;
174
175     vir = virtue_number(caster_ptr, V_UNLIFE);
176     if (vir) {
177         em_ptr->dam -= caster_ptr->virtues[vir - 1] / 10;
178     }
179
180     vir = virtue_number(caster_ptr, V_INDIVIDUALISM);
181     if (vir) {
182         em_ptr->dam -= caster_ptr->virtues[vir - 1] / 20;
183     }
184
185     msg_format(_("%sを見つめた。", "You stare into %s."), em_ptr->m_name);
186
187     if (common_saving_throw_charm(caster_ptr, em_ptr->dam, em_ptr->m_ptr) || !monster_living(em_ptr->m_ptr->r_idx)) {
188         em_ptr->note = _("には効果がなかった。", " is unaffected.");
189         em_ptr->obvious = FALSE;
190         if (one_in_(4))
191             em_ptr->m_ptr->mflag2 |= MFLAG2_NOPET;
192     } else if (has_aggravate(caster_ptr)) {
193         em_ptr->note = _("はあなたに敵意を抱いている!", " hates you too much!");
194         if (one_in_(4))
195             em_ptr->m_ptr->mflag2 |= MFLAG2_NOPET;
196     } else {
197         em_ptr->note = _("を支配した。", " is tamed!");
198         set_pet(caster_ptr, em_ptr->m_ptr);
199         if (em_ptr->r_ptr->flags3 & RF3_ANIMAL)
200             chg_virtue(caster_ptr, V_NATURE, 1);
201     }
202
203     em_ptr->dam = 0;
204     return PROCESS_CONTINUE;
205 }
206
207 static void effect_monster_domination_corrupted_addition(player_type *caster_ptr, effect_monster_type *em_ptr)
208 {
209     switch (randint1(4)) {
210     case 1:
211         set_stun(caster_ptr, caster_ptr->stun + em_ptr->dam / 2);
212         break;
213     case 2:
214         set_confused(caster_ptr, caster_ptr->confused + em_ptr->dam / 2);
215         break;
216     default: {
217         if (em_ptr->r_ptr->flags3 & RF3_NO_FEAR)
218             em_ptr->note = _("には効果がなかった。", " is unaffected.");
219         else
220             set_afraid(caster_ptr, caster_ptr->afraid + em_ptr->dam);
221     }
222     }
223 }
224
225 // Powerful demons & undead can turn a mindcrafter's attacks back on them.
226 static void effect_monster_domination_corrupted(player_type *caster_ptr, effect_monster_type *em_ptr)
227 {
228     bool is_corrupted = ((em_ptr->r_ptr->flags3 & (RF3_UNDEAD | RF3_DEMON)) != 0) && (em_ptr->r_ptr->level > caster_ptr->lev / 2) && (one_in_(2));
229     if (!is_corrupted) {
230         em_ptr->note = _("には効果がなかった。", " is unaffected.");
231         em_ptr->obvious = FALSE;
232         return;
233     }
234
235     em_ptr->note = NULL;
236     msg_format(_("%^sの堕落した精神は攻撃を跳ね返した!",
237                    (em_ptr->seen ? "%^s's corrupted mind backlashes your attack!" : "%^ss corrupted mind backlashes your attack!")),
238         em_ptr->m_name);
239     if (randint0(100 + em_ptr->r_ptr->level / 2) < caster_ptr->skill_sav) {
240         msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
241         return;
242     }
243
244     effect_monster_domination_corrupted_addition(caster_ptr, em_ptr);
245 }
246
247 static void effect_monster_domination_addition(effect_monster_type *em_ptr)
248 {
249     switch (randint1(4)) {
250     case 1:
251         em_ptr->do_stun = em_ptr->dam / 2;
252         break;
253     case 2:
254         em_ptr->do_conf = em_ptr->dam / 2;
255         break;
256     default:
257         em_ptr->do_fear = em_ptr->dam;
258     }
259 }
260
261 process_result effect_monster_domination(player_type *caster_ptr, effect_monster_type *em_ptr)
262 {
263     if (!is_hostile(em_ptr->m_ptr))
264         return PROCESS_CONTINUE;
265
266     if (em_ptr->seen)
267         em_ptr->obvious = TRUE;
268
269     if ((em_ptr->r_ptr->flags1 & (RF1_UNIQUE | RF1_QUESTOR)) || (em_ptr->r_ptr->flags3 & RF3_NO_CONF)
270         || (em_ptr->r_ptr->level > randint1((em_ptr->dam - 10) < 1 ? 1 : (em_ptr->dam - 10)) + 10)) {
271         if (((em_ptr->r_ptr->flags3 & RF3_NO_CONF) != 0) && is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr))
272             em_ptr->r_ptr->r_flags3 |= (RF3_NO_CONF);
273
274         em_ptr->do_conf = 0;
275         effect_monster_domination_corrupted(caster_ptr, em_ptr);
276         em_ptr->dam = 0;
277         return PROCESS_CONTINUE;
278     }
279
280     if (!common_saving_throw_charm(caster_ptr, em_ptr->dam, em_ptr->m_ptr)) {
281         em_ptr->note = _("があなたに隷属した。", " is in your thrall!");
282         set_pet(caster_ptr, em_ptr->m_ptr);
283         em_ptr->dam = 0;
284         return PROCESS_CONTINUE;
285     }
286
287     effect_monster_domination_addition(em_ptr);
288     em_ptr->dam = 0;
289     return PROCESS_CONTINUE;
290 }
291
292 static bool effect_monster_crusade_domination(player_type *caster_ptr, effect_monster_type *em_ptr)
293 {
294     if (((em_ptr->r_ptr->flags3 & RF3_GOOD) == 0) || caster_ptr->current_floor_ptr->inside_arena)
295         return FALSE;
296
297     if (em_ptr->r_ptr->flags3 & RF3_NO_CONF)
298         em_ptr->dam -= 50;
299     if (em_ptr->dam < 1)
300         em_ptr->dam = 1;
301
302     if (is_pet(em_ptr->m_ptr)) {
303         em_ptr->note = _("の動きが速くなった。", " starts moving faster.");
304         (void)set_monster_fast(caster_ptr, em_ptr->g_ptr->m_idx, monster_fast_remaining(em_ptr->m_ptr) + 100);
305         return TRUE;
306     }
307
308     if ((em_ptr->r_ptr->flags1 & RF1_QUESTOR) || (em_ptr->r_ptr->flags1 & RF1_UNIQUE) || (em_ptr->m_ptr->mflag2 & MFLAG2_NOPET)
309         || has_aggravate(caster_ptr) || ((em_ptr->r_ptr->level + 10) > randint1(em_ptr->dam))) {
310         if (one_in_(4))
311             em_ptr->m_ptr->mflag2 |= MFLAG2_NOPET;
312
313         return FALSE;
314     }
315
316     em_ptr->note = _("を支配した。", " is tamed!");
317     set_pet(caster_ptr, em_ptr->m_ptr);
318     (void)set_monster_fast(caster_ptr, em_ptr->g_ptr->m_idx, monster_fast_remaining(em_ptr->m_ptr) + 100);
319     if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr))
320         em_ptr->r_ptr->r_flags3 |= RF3_GOOD;
321
322     return TRUE;
323 }
324
325 process_result effect_monster_crusade(player_type *caster_ptr, effect_monster_type *em_ptr)
326 {
327     if (em_ptr->seen)
328         em_ptr->obvious = TRUE;
329     bool success = effect_monster_crusade_domination(caster_ptr, em_ptr);
330     if (success) {
331         em_ptr->dam = 0;
332         return PROCESS_CONTINUE;
333     }
334
335     if ((em_ptr->r_ptr->flags3 & RF3_NO_FEAR) == 0)
336         em_ptr->do_fear = randint1(90) + 10;
337     else if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr))
338         em_ptr->r_ptr->r_flags3 |= RF3_NO_FEAR;
339
340     em_ptr->dam = 0;
341     return PROCESS_CONTINUE;
342 }
343
344 static bool effect_monster_capture_attemption(player_type *caster_ptr, effect_monster_type *em_ptr, int capturable_hp)
345 {
346     if (em_ptr->m_ptr->hp >= randint0(capturable_hp))
347         return FALSE;
348
349     if (em_ptr->m_ptr->mflag2 & MFLAG2_CHAMELEON)
350         choose_new_monster(caster_ptr, em_ptr->g_ptr->m_idx, FALSE, MON_CHAMELEON);
351
352     msg_format(_("%sを捕えた!", "You capture %^s!"), em_ptr->m_name);
353     cap_mon = em_ptr->m_ptr->r_idx;
354     cap_mspeed = em_ptr->m_ptr->mspeed;
355     cap_hp = em_ptr->m_ptr->hp;
356     cap_maxhp = em_ptr->m_ptr->max_maxhp;
357     cap_nickname = em_ptr->m_ptr->nickname;
358     if ((em_ptr->g_ptr->m_idx == caster_ptr->riding) && process_fall_off_horse(caster_ptr, -1, FALSE))
359         msg_format(_("地面に落とされた。", "You have fallen from %s."), em_ptr->m_name);
360
361     delete_monster_idx(caster_ptr, em_ptr->g_ptr->m_idx);
362     return TRUE;
363 }
364
365 process_result effect_monster_capture(player_type *caster_ptr, effect_monster_type *em_ptr)
366 {
367     floor_type *floor_ptr = caster_ptr->current_floor_ptr;
368     int capturable_hp;
369     if ((floor_ptr->inside_quest && (quest[floor_ptr->inside_quest].type == QUEST_TYPE_KILL_ALL) && !is_pet(em_ptr->m_ptr))
370         || (em_ptr->r_ptr->flags1 & (RF1_UNIQUE)) || (em_ptr->r_ptr->flags7 & (RF7_NAZGUL)) || (em_ptr->r_ptr->flags7 & (RF7_UNIQUE2))
371         || (em_ptr->r_ptr->flags1 & RF1_QUESTOR) || em_ptr->m_ptr->parent_m_idx) {
372         msg_format(_("%sには効果がなかった。", "%s is unaffected."), em_ptr->m_name);
373         em_ptr->skipped = TRUE;
374         return PROCESS_CONTINUE;
375     }
376
377     if (is_pet(em_ptr->m_ptr))
378         capturable_hp = em_ptr->m_ptr->maxhp * 4L;
379     else if ((caster_ptr->pclass == CLASS_BEASTMASTER) && monster_living(em_ptr->m_ptr->r_idx))
380         capturable_hp = em_ptr->m_ptr->maxhp * 3 / 10;
381     else
382         capturable_hp = em_ptr->m_ptr->maxhp * 3 / 20;
383
384     if (em_ptr->m_ptr->hp >= capturable_hp) {
385         msg_format(_("もっと弱らせないと。", "You need to weaken %s more."), em_ptr->m_name);
386         em_ptr->skipped = TRUE;
387         return PROCESS_CONTINUE;
388     }
389
390     if (effect_monster_capture_attemption(caster_ptr, em_ptr, capturable_hp))
391         return PROCESS_TRUE;
392
393     msg_format(_("うまく捕まえられなかった。", "You failed to capture %s."), em_ptr->m_name);
394     em_ptr->skipped = TRUE;
395     return PROCESS_CONTINUE;
396 }