OSDN Git Service

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