OSDN Git Service

set trivial flags
[jnethack/source.git] / src / minion.c
1 /* NetHack 3.6  minion.c        $NHDT-Date: 1544998886 2018/12/16 22:21:26 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.40 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2008. */
4 /* NetHack may be freely redistributed.  See license for details. */
5
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2019            */
9 /* JNetHack may be freely redistributed.  See license for details. */
10
11 #include "hack.h"
12
13 void
14 newemin(mtmp)
15 struct monst *mtmp;
16 {
17     if (!mtmp->mextra)
18         mtmp->mextra = newmextra();
19     if (!EMIN(mtmp)) {
20         EMIN(mtmp) = (struct emin *) alloc(sizeof(struct emin));
21         (void) memset((genericptr_t) EMIN(mtmp), 0, sizeof(struct emin));
22     }
23 }
24
25 void
26 free_emin(mtmp)
27 struct monst *mtmp;
28 {
29     if (mtmp->mextra && EMIN(mtmp)) {
30         free((genericptr_t) EMIN(mtmp));
31         EMIN(mtmp) = (struct emin *) 0;
32     }
33     mtmp->isminion = 0;
34 }
35
36 /* count the number of monsters on the level */
37 int
38 monster_census(spotted)
39 boolean spotted; /* seen|sensed vs all */
40 {
41     struct monst *mtmp;
42     int count = 0;
43
44     for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
45         if (DEADMONSTER(mtmp))
46             continue;
47         if (spotted && !canspotmon(mtmp))
48             continue;
49         ++count;
50     }
51     return count;
52 }
53
54 /* mon summons a monster */
55 int
56 msummon(mon)
57 struct monst *mon;
58 {
59     struct permonst *ptr;
60     int dtype = NON_PM, cnt = 0, result = 0, census;
61     aligntyp atyp;
62     struct monst *mtmp;
63
64     if (mon) {
65         ptr = mon->data;
66
67         if (uwep && uwep->oartifact == ART_DEMONBANE && is_demon(ptr)) {
68             if (canseemon(mon))
69 /*JP
70                 pline("%s looks puzzled for a moment.", Monnam(mon));
71 */
72                 pline("%s\82Í\8f­\82µ\8d¢\98f\82µ\82Ä\82¢\82é\82æ\82¤\82¾\81D", Monnam(mon));
73             return 0;
74         }
75
76         atyp = mon->ispriest ? EPRI(mon)->shralign
77                              : mon->isminion ? EMIN(mon)->min_align
78                                              : (ptr->maligntyp == A_NONE)
79                                                    ? A_NONE
80                                                    : sgn(ptr->maligntyp);
81     } else {
82         ptr = &mons[PM_WIZARD_OF_YENDOR];
83         atyp = (ptr->maligntyp == A_NONE) ? A_NONE : sgn(ptr->maligntyp);
84     }
85
86     if (is_dprince(ptr) || (ptr == &mons[PM_WIZARD_OF_YENDOR])) {
87         dtype = (!rn2(20)) ? dprince(atyp) : (!rn2(4)) ? dlord(atyp)
88                                                        : ndemon(atyp);
89         cnt = (!rn2(4) && is_ndemon(&mons[dtype])) ? 2 : 1;
90     } else if (is_dlord(ptr)) {
91         dtype = (!rn2(50)) ? dprince(atyp) : (!rn2(20)) ? dlord(atyp)
92                                                         : ndemon(atyp);
93         cnt = (!rn2(4) && is_ndemon(&mons[dtype])) ? 2 : 1;
94     } else if (is_ndemon(ptr)) {
95         dtype = (!rn2(20)) ? dlord(atyp) : (!rn2(6)) ? ndemon(atyp)
96                                                      : monsndx(ptr);
97         cnt = 1;
98     } else if (is_lminion(mon)) {
99         dtype = (is_lord(ptr) && !rn2(20))
100                     ? llord()
101                     : (is_lord(ptr) || !rn2(6)) ? lminion() : monsndx(ptr);
102         cnt = (!rn2(4) && !is_lord(&mons[dtype])) ? 2 : 1;
103     } else if (ptr == &mons[PM_ANGEL]) {
104         /* non-lawful angels can also summon */
105         if (!rn2(6)) {
106             switch (atyp) { /* see summon_minion */
107             case A_NEUTRAL:
108                 dtype = PM_AIR_ELEMENTAL + rn2(4);
109                 break;
110             case A_CHAOTIC:
111             case A_NONE:
112                 dtype = ndemon(atyp);
113                 break;
114             }
115         } else {
116             dtype = PM_ANGEL;
117         }
118         cnt = (!rn2(4) && !is_lord(&mons[dtype])) ? 2 : 1;
119     }
120
121     if (dtype == NON_PM)
122         return 0;
123
124     /* sanity checks */
125     if (cnt > 1 && (mons[dtype].geno & G_UNIQ))
126         cnt = 1;
127     /*
128      * If this daemon is unique and being re-summoned (the only way we
129      * could get this far with an extinct dtype), try another.
130      */
131     if (mvitals[dtype].mvflags & G_GONE) {
132         dtype = ndemon(atyp);
133         if (dtype == NON_PM)
134             return 0;
135     }
136
137     /* some candidates can generate a group of monsters, so simple
138        count of non-null makemon() result is not sufficient */
139     census = monster_census(FALSE);
140
141     while (cnt > 0) {
142         mtmp = makemon(&mons[dtype], u.ux, u.uy, MM_EMIN);
143         if (mtmp) {
144             result++;
145             /* an angel's alignment should match the summoner */
146             if (dtype == PM_ANGEL) {
147                 mtmp->isminion = 1;
148                 EMIN(mtmp)->min_align = atyp;
149                 /* renegade if same alignment but not peaceful
150                    or peaceful but different alignment */
151                 EMIN(mtmp)->renegade =
152                     (atyp != u.ualign.type) ^ !mtmp->mpeaceful;
153             }
154             if (is_demon(ptr) && canseemon(mtmp))
155                 pline("%s appears in a cloud of smoke!", Amonnam(mtmp));
156         }
157         cnt--;
158     }
159
160     /* how many monsters exist now compared to before? */
161     if (result)
162         result = monster_census(FALSE) - census;
163
164     return result;
165 }
166
167 void
168 summon_minion(alignment, talk)
169 aligntyp alignment;
170 boolean talk;
171 {
172     register struct monst *mon;
173     int mnum;
174
175     switch ((int) alignment) {
176     case A_LAWFUL:
177         mnum = lminion();
178         break;
179     case A_NEUTRAL:
180         mnum = PM_AIR_ELEMENTAL + rn2(4);
181         break;
182     case A_CHAOTIC:
183     case A_NONE:
184         mnum = ndemon(alignment);
185         break;
186     default:
187         impossible("unaligned player?");
188         mnum = ndemon(A_NONE);
189         break;
190     }
191     if (mnum == NON_PM) {
192         mon = 0;
193     } else if (mnum == PM_ANGEL) {
194         mon = makemon(&mons[mnum], u.ux, u.uy, MM_EMIN);
195         if (mon) {
196             mon->isminion = 1;
197             EMIN(mon)->min_align = alignment;
198             EMIN(mon)->renegade = FALSE;
199         }
200     } else if (mnum != PM_SHOPKEEPER && mnum != PM_GUARD
201                && mnum != PM_ALIGNED_PRIEST && mnum != PM_HIGH_PRIEST) {
202         /* This was mons[mnum].pxlth == 0 but is this restriction
203            appropriate or necessary now that the structures are separate? */
204         mon = makemon(&mons[mnum], u.ux, u.uy, MM_EMIN);
205         if (mon) {
206             mon->isminion = 1;
207             EMIN(mon)->min_align = alignment;
208             EMIN(mon)->renegade = FALSE;
209         }
210     } else {
211         mon = makemon(&mons[mnum], u.ux, u.uy, NO_MM_FLAGS);
212     }
213     if (mon) {
214         if (talk) {
215 /*JP
216             pline_The("voice of %s booms:", align_gname(alignment));
217 */
218             pline("%s\82Ì\90º\82ª\8b¿\82¢\82½:", align_gname(alignment));
219 /*JP
220             verbalize("Thou shalt pay for thine indiscretion!");
221 */
222             verbalize("\93ð\81C\96³\95ª\95Ê\82È\82é\8ds\82¢\82Ì\94±\82ð\8eó\82¯\82é\82×\82µ\81I");
223             if (!Blind)
224 /*JP
225                 pline("%s appears before you.", Amonnam(mon));
226 */
227                 pline("%s\82ª\82 \82È\82½\82Ì\91O\82É\8c»\82í\82ê\82½\81D", Amonnam(mon));
228             mon->mstrategy &= ~STRAT_APPEARMSG;
229         }
230         mon->mpeaceful = FALSE;
231         /* don't call set_malign(); player was naughty */
232     }
233 }
234
235 #define Athome (Inhell && (mtmp->cham == NON_PM))
236
237 /* returns 1 if it won't attack. */
238 int
239 demon_talk(mtmp)
240 register struct monst *mtmp;
241 {
242     long cash, demand, offer;
243
244     if (uwep && uwep->oartifact == ART_EXCALIBUR) {
245 /*JP
246         pline("%s looks very angry.", Amonnam(mtmp));
247 */
248         pline("%s\82Í\82Æ\82Ä\82à\93{\82Á\82Ä\82¢\82é\82æ\82¤\82É\8c©\82¦\82é\81D", Amonnam(mtmp));
249         mtmp->mpeaceful = mtmp->mtame = 0;
250         set_malign(mtmp);
251         newsym(mtmp->mx, mtmp->my);
252         return 0;
253     }
254
255     if (is_fainted()) {
256         reset_faint(); /* if fainted - wake up */
257     } else {
258         stop_occupation();
259         if (multi > 0) {
260             nomul(0);
261             unmul((char *) 0);
262         }
263     }
264
265     /* Slight advantage given. */
266     if (is_dprince(mtmp->data) && mtmp->minvis) {
267         boolean wasunseen = !canspotmon(mtmp);
268
269         mtmp->minvis = mtmp->perminvis = 0;
270         if (wasunseen && canspotmon(mtmp)) {
271 /*JP
272             pline("%s appears before you.", Amonnam(mtmp));
273 */
274             pline("%s\82ª\96Ú\82Ì\91O\82É\8c»\82í\82ê\82½\81D", Amonnam(mtmp));
275             mtmp->mstrategy &= ~STRAT_APPEARMSG;
276         }
277         newsym(mtmp->mx, mtmp->my);
278     }
279     if (youmonst.data->mlet == S_DEMON) { /* Won't blackmail their own. */
280 #if 0 /*JP:T*/
281         pline("%s says, \"Good hunting, %s.\"", Amonnam(mtmp),
282               flags.female ? "Sister" : "Brother");
283 #else
284         pline("%s\82Í\8c¾\82Á\82½\81u\82æ\82¤\8cZ%s\81I\81v\81D\82»\82µ\82Ä\8fÁ\82¦\82½\81D", Amonnam(mtmp),
285               flags.female ? "\96\85" : "\92í");
286 #endif
287         if (!tele_restrict(mtmp))
288             (void) rloc(mtmp, TRUE);
289         return 1;
290     }
291     cash = money_cnt(invent);
292     demand =
293         (cash * (rnd(80) + 20 * Athome))
294         / (100 * (1 + (sgn(u.ualign.type) == sgn(mtmp->data->maligntyp))));
295
296     if (!demand || multi < 0) { /* you have no gold or can't move */
297         mtmp->mpeaceful = 0;
298         set_malign(mtmp);
299         return 0;
300     } else {
301         /* make sure that the demand is unmeetable if the monster
302            has the Amulet, preventing monster from being satisfied
303            and removed from the game (along with said Amulet...) */
304         if (mon_has_amulet(mtmp))
305             demand = cash + (long) rn1(1000, 40);
306
307 #if 0 /*JP:T*/
308         pline("%s demands %ld %s for safe passage.", Amonnam(mtmp), demand,
309               currency(demand));
310 #else
311         pline("%s\82Í\92Ê\8ds\97¿\82Æ\82µ\82Ä%ld%s\97v\8b\81\82µ\82½\81D", Amonnam(mtmp), demand,
312               currency(demand));
313 #endif
314
315         if ((offer = bribe(mtmp)) >= demand) {
316 /*JP
317             pline("%s vanishes, laughing about cowardly mortals.",
318 */
319             pline("\89°\95a\82È\92è\96½\82Ì\82à\82Ì\82ð\8fÎ\82¢\82È\82ª\82ç\81C%s\82Í\8fÁ\82¦\82½\81D",
320                   Amonnam(mtmp));
321         } else if (offer > 0L
322                    && (long) rnd(5 * ACURR(A_CHA)) > (demand - offer)) {
323 /*JP
324             pline("%s scowls at you menacingly, then vanishes.",
325 */
326             pline("%s\82Í\82 \82È\82½\82ð\88Ð\8ad\82µ\81C\8fÁ\82¦\82½\81D",
327                   Amonnam(mtmp));
328         } else {
329 /*JP
330             pline("%s gets angry...", Amonnam(mtmp));
331 */
332             pline("%s\82Í\93{\82Á\82½\81D\81D\81D", Amonnam(mtmp));
333             mtmp->mpeaceful = 0;
334             set_malign(mtmp);
335             return 0;
336         }
337     }
338     mongone(mtmp);
339     return 1;
340 }
341
342 long
343 bribe(mtmp)
344 struct monst *mtmp;
345 {
346     char buf[BUFSZ] = DUMMY;
347     long offer;
348     long umoney = money_cnt(invent);
349
350 /*JP
351     getlin("How much will you offer?", buf);
352 */
353     getlin("\82¨\8bà\82ð\82¢\82­\82ç\97^\82¦\82é\81H", buf);
354     if (sscanf(buf, "%ld", &offer) != 1)
355         offer = 0L;
356
357     /*Michael Paddon -- fix for negative offer to monster*/
358     /*JAR880815 - */
359     if (offer < 0L) {
360 /*JP
361         You("try to shortchange %s, but fumble.", mon_nam(mtmp));
362 */
363         You("%s\82ð\82¾\82Ü\82»\82¤\82Æ\82µ\82½\82ª\81C\8e¸\94s\82µ\82½\81D", mon_nam(mtmp));
364         return 0L;
365     } else if (offer == 0L) {
366 /*JP
367         You("refuse.");
368 */
369         You("\8b\91\82ñ\82¾\81D");
370         return 0L;
371     } else if (offer >= umoney) {
372 /*JP
373         You("give %s all your gold.", mon_nam(mtmp));
374 */
375         You("%s\82É\82¨\8bà\82ð\91S\82Ä\97^\82¦\82½\81D", mon_nam(mtmp));
376         offer = umoney;
377     } else {
378 /*JP
379         You("give %s %ld %s.", mon_nam(mtmp), offer, currency(offer));
380 */
381         You("%s\82É%ld%s\97^\82¦\82½\81D", mon_nam(mtmp), offer, currency(offer));
382     }
383     (void) money2mon(mtmp, offer);
384     context.botl = 1;
385     return offer;
386 }
387
388 int
389 dprince(atyp)
390 aligntyp atyp;
391 {
392     int tryct, pm;
393
394     for (tryct = !In_endgame(&u.uz) ? 20 : 0; tryct > 0; --tryct) {
395         pm = rn1(PM_DEMOGORGON + 1 - PM_ORCUS, PM_ORCUS);
396         if (!(mvitals[pm].mvflags & G_GONE)
397             && (atyp == A_NONE || sgn(mons[pm].maligntyp) == sgn(atyp)))
398             return pm;
399     }
400     return dlord(atyp); /* approximate */
401 }
402
403 int
404 dlord(atyp)
405 aligntyp atyp;
406 {
407     int tryct, pm;
408
409     for (tryct = !In_endgame(&u.uz) ? 20 : 0; tryct > 0; --tryct) {
410         pm = rn1(PM_YEENOGHU + 1 - PM_JUIBLEX, PM_JUIBLEX);
411         if (!(mvitals[pm].mvflags & G_GONE)
412             && (atyp == A_NONE || sgn(mons[pm].maligntyp) == sgn(atyp)))
413             return pm;
414     }
415     return ndemon(atyp); /* approximate */
416 }
417
418 /* create lawful (good) lord */
419 int
420 llord()
421 {
422     if (!(mvitals[PM_ARCHON].mvflags & G_GONE))
423         return PM_ARCHON;
424
425     return lminion(); /* approximate */
426 }
427
428 int
429 lminion()
430 {
431     int tryct;
432     struct permonst *ptr;
433
434     for (tryct = 0; tryct < 20; tryct++) {
435         ptr = mkclass(S_ANGEL, 0);
436         if (ptr && !is_lord(ptr))
437             return monsndx(ptr);
438     }
439
440     return NON_PM;
441 }
442
443 int
444 ndemon(atyp)
445 aligntyp atyp; /* A_NONE is used for 'any alignment' */
446 {
447     struct permonst *ptr;
448
449     /*
450      * 3.6.2:  [fix #H2204, 22-Dec-2010, eight years later...]
451      * pick a correctly aligned demon in one try.  This used to
452      * use mkclass() to choose a random demon type and keep trying
453      * (up to 20 times) until it got one with the desired alignment.
454      * mkclass_aligned() skips wrongly aligned potential candidates.
455      * [The only neutral demons are djinni and mail daemon and
456      * mkclass() won't pick them, but call it anyway in case either
457      * aspect of that changes someday.]
458      */
459 #if 0
460     if (atyp == A_NEUTRAL)
461         return NON_PM;
462 #endif
463     ptr = mkclass_aligned(S_DEMON, 0, atyp);
464     return (ptr && is_ndemon(ptr)) ? monsndx(ptr) : NON_PM;
465 }
466
467 /* guardian angel has been affected by conflict so is abandoning hero */
468 void
469 lose_guardian_angel(mon)
470 struct monst *mon; /* if null, angel hasn't been created yet */
471 {
472     coord mm;
473     int i;
474
475     if (mon) {
476         if (canspotmon(mon)) {
477             if (!Deaf) {
478 /*JP
479                 pline("%s rebukes you, saying:", Monnam(mon));
480 */
481                 pline("%s\82Í\82 \82È\82½\82ð\94ñ\93ï\82µ\82½\81F", Monnam(mon));
482 /*JP
483                 verbalize("Since you desire conflict, have some more!");
484 */
485                 verbalize("\93¬\91\88\82ð\96]\82ñ\82Å\82¢\82é\82æ\82¤\82¾\82©\82ç\81C\82à\82Á\82Æ\97^\82¦\82Ä\82â\82ë\82¤\81I");
486             } else {
487 /*JP
488                 pline("%s vanishes!", Monnam(mon));
489 */
490                 pline("%s\82Í\8fÁ\82¦\82½\81I", Monnam(mon));
491             }
492         }
493         mongone(mon);
494     }
495     /* create 2 to 4 hostile angels to replace the lost guardian */
496     for (i = rn1(3, 2); i > 0; --i) {
497         mm.x = u.ux;
498         mm.y = u.uy;
499         if (enexto(&mm, mm.x, mm.y, &mons[PM_ANGEL]))
500             (void) mk_roamer(&mons[PM_ANGEL], u.ualign.type, mm.x, mm.y,
501                              FALSE);
502     }
503 }
504
505 /* just entered the Astral Plane; receive tame guardian angel if worthy */
506 void
507 gain_guardian_angel()
508 {
509     struct monst *mtmp;
510     struct obj *otmp;
511     coord mm;
512
513     Hear_again(); /* attempt to cure any deafness now (divine
514                      message will be heard even if that fails) */
515     if (Conflict) {
516 /*JP
517         pline("A voice booms:");
518 */
519         pline("\90º\82ª\8b¿\82¢\82½:");
520 /*JP
521         verbalize("Thy desire for conflict shall be fulfilled!");
522 */
523         verbalize("\81u\93ð\82Ì\93¬\91\88\82Ö\82Ì\96]\82Ý\81C\82©\82È\82¦\82ç\82ê\82é\82×\82µ\81I\81v");
524         /* send in some hostile angels instead */
525         lose_guardian_angel((struct monst *) 0);
526     } else if (u.ualign.record > 8) { /* fervent */
527 /*JP
528         pline("A voice whispers:");
529 */
530         pline("\82³\82³\82â\82«\90º\82ª\95·\82±\82¦\82½:");
531 /*JP
532         verbalize("Thou hast been worthy of me!");
533 */
534         verbalize("\81u\93ð\81C\89ä\82ª\95]\89¿\82ð\93¾\82½\82è\81I\81v");
535         mm.x = u.ux;
536         mm.y = u.uy;
537         if (enexto(&mm, mm.x, mm.y, &mons[PM_ANGEL])
538             && (mtmp = mk_roamer(&mons[PM_ANGEL], u.ualign.type, mm.x, mm.y,
539                                  TRUE)) != 0) {
540             mtmp->mstrategy &= ~STRAT_APPEARMSG;
541             if (!Blind)
542 /*JP
543                 pline("An angel appears near you.");
544 */
545                 pline("\93V\8eg\82ª\82 \82È\82½\82Ì\82»\82Î\82É\8c»\82í\82ê\82½\81D");
546             else
547 /*JP
548                 You_feel("the presence of a friendly angel near you.");
549 */
550                 You("\8bß\82­\82É\97F\8dD\93I\82È\93V\8eg\82Ì\91\8dÝ\82ð\8a´\82\82½\81D");
551             /* guardian angel -- the one case mtame doesn't
552              * imply an edog structure, so we don't want to
553              * call tamedog().
554              */
555             mtmp->mtame = 10;
556             /* make him strong enough vs. endgame foes */
557             mtmp->m_lev = rn1(8, 15);
558             mtmp->mhp = mtmp->mhpmax =
559                 d((int) mtmp->m_lev, 10) + 30 + rnd(30);
560             if ((otmp = select_hwep(mtmp)) == 0) {
561                 otmp = mksobj(SILVER_SABER, FALSE, FALSE);
562                 if (mpickobj(mtmp, otmp))
563                     panic("merged weapon?");
564             }
565             bless(otmp);
566             if (otmp->spe < 4)
567                 otmp->spe += rnd(4);
568             if ((otmp = which_armor(mtmp, W_ARMS)) == 0
569                 || otmp->otyp != SHIELD_OF_REFLECTION) {
570                 (void) mongets(mtmp, AMULET_OF_REFLECTION);
571                 m_dowear(mtmp, TRUE);
572             }
573         }
574     }
575 }
576
577 /*minion.c*/