1 /* NetHack 3.6 minion.c $NHDT-Date: 1575245071 2019/12/02 00:04:31 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.44 $ */
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. */
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2020 */
9 /* JNetHack may be freely redistributed. See license for details. */
18 mtmp->mextra = newmextra();
20 EMIN(mtmp) = (struct emin *) alloc(sizeof(struct emin));
21 (void) memset((genericptr_t) EMIN(mtmp), 0, sizeof(struct emin));
29 if (mtmp->mextra && EMIN(mtmp)) {
30 free((genericptr_t) EMIN(mtmp));
31 EMIN(mtmp) = (struct emin *) 0;
36 /* count the number of monsters on the level */
38 monster_census(spotted)
39 boolean spotted; /* seen|sensed vs all */
44 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
45 if (DEADMONSTER(mtmp))
47 if (spotted && !canspotmon(mtmp))
54 /* mon summons a monster */
60 int dtype = NON_PM, cnt = 0, result = 0, census;
67 if (uwep && uwep->oartifact == ART_DEMONBANE && is_demon(ptr)) {
70 pline("%s looks puzzled for a moment.", Monnam(mon));
72 pline("%s
\82Í
\8f
\82µ
\8d¢
\98f
\82µ
\82Ä
\82¢
\82é
\82æ
\82¤
\82¾
\81D", Monnam(mon));
76 atyp = mon->ispriest ? EPRI(mon)->shralign
77 : mon->isminion ? EMIN(mon)->min_align
78 : (ptr->maligntyp == A_NONE)
80 : sgn(ptr->maligntyp);
82 ptr = &mons[PM_WIZARD_OF_YENDOR];
83 atyp = (ptr->maligntyp == A_NONE) ? A_NONE : sgn(ptr->maligntyp);
86 if (is_dprince(ptr) || (ptr == &mons[PM_WIZARD_OF_YENDOR])) {
87 dtype = (!rn2(20)) ? dprince(atyp) : (!rn2(4)) ? dlord(atyp)
89 cnt = ((dtype != NON_PM)
90 && !rn2(4) && is_ndemon(&mons[dtype])) ? 2 : 1;
91 } else if (is_dlord(ptr)) {
92 dtype = (!rn2(50)) ? dprince(atyp) : (!rn2(20)) ? dlord(atyp)
94 cnt = ((dtype != NON_PM)
95 && !rn2(4) && is_ndemon(&mons[dtype])) ? 2 : 1;
96 } else if (is_ndemon(ptr)) {
97 dtype = (!rn2(20)) ? dlord(atyp) : (!rn2(6)) ? ndemon(atyp)
100 } else if (is_lminion(mon)) {
101 dtype = (is_lord(ptr) && !rn2(20))
103 : (is_lord(ptr) || !rn2(6)) ? lminion() : monsndx(ptr);
104 cnt = ((dtype != NON_PM)
105 && !rn2(4) && !is_lord(&mons[dtype])) ? 2 : 1;
106 } else if (ptr == &mons[PM_ANGEL]) {
107 /* non-lawful angels can also summon */
109 switch (atyp) { /* see summon_minion */
111 dtype = PM_AIR_ELEMENTAL + rn2(4);
115 dtype = ndemon(atyp);
121 cnt = ((dtype != NON_PM)
122 && !rn2(4) && !is_lord(&mons[dtype])) ? 2 : 1;
129 if (cnt > 1 && (mons[dtype].geno & G_UNIQ))
132 * If this daemon is unique and being re-summoned (the only way we
133 * could get this far with an extinct dtype), try another.
135 if (mvitals[dtype].mvflags & G_GONE) {
136 dtype = ndemon(atyp);
141 /* some candidates can generate a group of monsters, so simple
142 count of non-null makemon() result is not sufficient */
143 census = monster_census(FALSE);
146 mtmp = makemon(&mons[dtype], u.ux, u.uy, MM_EMIN);
149 /* an angel's alignment should match the summoner */
150 if (dtype == PM_ANGEL) {
152 EMIN(mtmp)->min_align = atyp;
153 /* renegade if same alignment but not peaceful
154 or peaceful but different alignment */
155 EMIN(mtmp)->renegade =
156 (atyp != u.ualign.type) ^ !mtmp->mpeaceful;
158 if (is_demon(ptr) && canseemon(mtmp))
160 pline("%s appears in a cloud of smoke!", Amonnam(mtmp));
162 pline("%s
\82ª
\89\8c\82Ì
\92\86\82©
\82ç
\8c»
\82ê
\82½
\81I", Amonnam(mtmp));
167 /* how many monsters exist now compared to before? */
169 result = monster_census(FALSE) - census;
175 summon_minion(alignment, talk)
179 register struct monst *mon;
182 switch ((int) alignment) {
187 mnum = PM_AIR_ELEMENTAL + rn2(4);
191 mnum = ndemon(alignment);
194 impossible("unaligned player?");
195 mnum = ndemon(A_NONE);
198 if (mnum == NON_PM) {
200 } else if (mnum == PM_ANGEL) {
201 mon = makemon(&mons[mnum], u.ux, u.uy, MM_EMIN);
204 EMIN(mon)->min_align = alignment;
205 EMIN(mon)->renegade = FALSE;
207 } else if (mnum != PM_SHOPKEEPER && mnum != PM_GUARD
208 && mnum != PM_ALIGNED_PRIEST && mnum != PM_HIGH_PRIEST) {
209 /* This was mons[mnum].pxlth == 0 but is this restriction
210 appropriate or necessary now that the structures are separate? */
211 mon = makemon(&mons[mnum], u.ux, u.uy, MM_EMIN);
214 EMIN(mon)->min_align = alignment;
215 EMIN(mon)->renegade = FALSE;
218 mon = makemon(&mons[mnum], u.ux, u.uy, NO_MM_FLAGS);
224 pline_The("voice of %s booms:", align_gname(alignment));
226 pline("%s
\82Ì
\90º
\82ª
\8b¿
\82¢
\82½:", align_gname(alignment));
229 You_feel("%s booming voice:",
230 s_suffix(align_gname(alignment)));
232 You_feel("%s
\82Ì
\8b¿
\82
\90º
\82ð
\8a´
\82¶
\82½:",
233 s_suffix(align_gname(alignment)));
236 verbalize("Thou shalt pay for thine indiscretion!");
238 verbalize("
\93ð
\81C
\96³
\95ª
\95Ê
\82È
\82é
\8ds
\82¢
\82Ì
\94±
\82ð
\8eó
\82¯
\82é
\82×
\82µ
\81I");
241 pline("%s appears before you.", Amonnam(mon));
243 pline("%s
\82ª
\82 \82È
\82½
\82Ì
\91O
\82É
\8c»
\82í
\82ê
\82½
\81D", Amonnam(mon));
244 mon->mstrategy &= ~STRAT_APPEARMSG;
246 mon->mpeaceful = FALSE;
247 /* don't call set_malign(); player was naughty */
251 #define Athome (Inhell && (mtmp->cham == NON_PM))
253 /* returns 1 if it won't attack. */
256 register struct monst *mtmp;
258 long cash, demand, offer;
260 if (uwep && uwep->oartifact == ART_EXCALIBUR) {
262 pline("%s looks very angry.", Amonnam(mtmp));
264 pline("%s
\82Í
\82Æ
\82Ä
\82à
\93{
\82Á
\82Ä
\82¢
\82é
\82æ
\82¤
\82É
\8c©
\82¦
\82é
\81D", Amonnam(mtmp));
265 mtmp->mpeaceful = mtmp->mtame = 0;
267 newsym(mtmp->mx, mtmp->my);
272 reset_faint(); /* if fainted - wake up */
281 /* Slight advantage given. */
282 if (is_dprince(mtmp->data) && mtmp->minvis) {
283 boolean wasunseen = !canspotmon(mtmp);
285 mtmp->minvis = mtmp->perminvis = 0;
286 if (wasunseen && canspotmon(mtmp)) {
288 pline("%s appears before you.", Amonnam(mtmp));
290 pline("%s
\82ª
\96Ú
\82Ì
\91O
\82É
\8c»
\82í
\82ê
\82½
\81D", Amonnam(mtmp));
291 mtmp->mstrategy &= ~STRAT_APPEARMSG;
293 newsym(mtmp->mx, mtmp->my);
295 if (youmonst.data->mlet == S_DEMON) { /* Won't blackmail their own. */
298 pline("%s says, \"Good hunting, %s.\"", Amonnam(mtmp),
299 flags.female ? "Sister" : "Brother");
301 pline("%s
\82Í
\8c¾
\82Á
\82½
\81u
\82æ
\82¤
\8cZ%s
\81I
\81v
\81D
\82»
\82µ
\82Ä
\8fÁ
\82¦
\82½
\81D", Amonnam(mtmp),
302 flags.female ? "
\96\85" : "
\92í");
304 else if (canseemon(mtmp))
306 pline("%s says something.", Amonnam(mtmp));
308 pline("%s
\82Í
\89½
\82©
\82ð
\8c¾
\82Á
\82½
\81D", Amonnam(mtmp));
309 if (!tele_restrict(mtmp))
310 (void) rloc(mtmp, TRUE);
313 cash = money_cnt(invent);
314 demand = (cash * (rnd(80) + 20 * Athome))
315 / (100 * (1 + (sgn(u.ualign.type) == sgn(mtmp->data->maligntyp))));
317 if (!demand || multi < 0) { /* you have no gold or can't move */
322 /* make sure that the demand is unmeetable if the monster
323 has the Amulet, preventing monster from being satisfied
324 and removed from the game (along with said Amulet...) */
325 /* [actually the Amulet is safe; it would be dropped when
326 mongone() gets rid of the monster; force combat anyway;
327 also make it unmeetable if the player is Deaf, to simplify
328 handling that case as player-won't-pay] */
329 if (mon_has_amulet(mtmp) || Deaf)
330 /* 125: 5*25 in case hero has maximum possible charisma */
331 demand = cash + (long) rn1(1000, 125);
335 pline("%s demands %ld %s for safe passage.",
336 Amonnam(mtmp), demand, currency(demand));
338 pline("%s
\82Í
\92Ê
\8ds
\97¿
\82Æ
\82µ
\82Ä%ld%s
\97v
\8b\81\82µ
\82½
\81D",
339 Amonnam(mtmp), demand, currency(demand));
341 else if (canseemon(mtmp))
343 pline("%s seems to be demanding something.", Amonnam(mtmp));
345 pline("%s
\82Í
\89½
\82©
\82ð
\97v
\8b\81\82µ
\82Ä
\82¢
\82é
\82æ
\82¤
\82¾
\81D", Amonnam(mtmp));
348 if (!Deaf && ((offer = bribe(mtmp)) >= demand)) {
350 pline("%s vanishes, laughing about cowardly mortals.",
352 pline("
\89°
\95a
\82È
\92è
\96½
\82Ì
\82à
\82Ì
\82ð
\8fÎ
\82¢
\82È
\82ª
\82ç
\81C%s
\82Í
\8fÁ
\82¦
\82½
\81D",
354 } else if (offer > 0L
355 && (long) rnd(5 * ACURR(A_CHA)) > (demand - offer)) {
357 pline("%s scowls at you menacingly, then vanishes.",
359 pline("%s
\82Í
\82 \82È
\82½
\82ð
\88Ð
\8ad
\82µ
\81C
\8fÁ
\82¦
\82½
\81D",
363 pline("%s gets angry...", Amonnam(mtmp));
365 pline("%s
\82Í
\93{
\82Á
\82½
\81D
\81D
\81D", Amonnam(mtmp));
379 char buf[BUFSZ] = DUMMY;
381 long umoney = money_cnt(invent);
384 getlin("How much will you offer?", buf);
386 getlin("
\82¨
\8bà
\82ð
\82¢
\82
\82ç
\97^
\82¦
\82é
\81H", buf);
387 if (sscanf(buf, "%ld", &offer) != 1)
390 /*Michael Paddon -- fix for negative offer to monster*/
394 You("try to shortchange %s, but fumble.", mon_nam(mtmp));
396 You("%s
\82ð
\82¾
\82Ü
\82»
\82¤
\82Æ
\82µ
\82½
\82ª
\81C
\8e¸
\94s
\82µ
\82½
\81D", mon_nam(mtmp));
398 } else if (offer == 0L) {
402 You("
\8b\91\82ñ
\82¾
\81D");
404 } else if (offer >= umoney) {
406 You("give %s all your gold.", mon_nam(mtmp));
408 You("%s
\82É
\82¨
\8bà
\82ð
\91S
\82Ä
\97^
\82¦
\82½
\81D", mon_nam(mtmp));
412 You("give %s %ld %s.", mon_nam(mtmp), offer, currency(offer));
414 You("%s
\82É%ld%s
\97^
\82¦
\82½
\81D", mon_nam(mtmp), offer, currency(offer));
416 (void) money2mon(mtmp, offer);
427 for (tryct = !In_endgame(&u.uz) ? 20 : 0; tryct > 0; --tryct) {
428 pm = rn1(PM_DEMOGORGON + 1 - PM_ORCUS, PM_ORCUS);
429 if (!(mvitals[pm].mvflags & G_GONE)
430 && (atyp == A_NONE || sgn(mons[pm].maligntyp) == sgn(atyp)))
433 return dlord(atyp); /* approximate */
442 for (tryct = !In_endgame(&u.uz) ? 20 : 0; tryct > 0; --tryct) {
443 pm = rn1(PM_YEENOGHU + 1 - PM_JUIBLEX, PM_JUIBLEX);
444 if (!(mvitals[pm].mvflags & G_GONE)
445 && (atyp == A_NONE || sgn(mons[pm].maligntyp) == sgn(atyp)))
448 return ndemon(atyp); /* approximate */
451 /* create lawful (good) lord */
455 if (!(mvitals[PM_ARCHON].mvflags & G_GONE))
458 return lminion(); /* approximate */
465 struct permonst *ptr;
467 for (tryct = 0; tryct < 20; tryct++) {
468 ptr = mkclass(S_ANGEL, 0);
469 if (ptr && !is_lord(ptr))
478 aligntyp atyp; /* A_NONE is used for 'any alignment' */
480 struct permonst *ptr;
483 * 3.6.2: [fixed #H2204, 22-Dec-2010, eight years later...]
484 * pick a correctly aligned demon in one try. This used to
485 * use mkclass() to choose a random demon type and keep trying
486 * (up to 20 times) until it got one with the desired alignment.
487 * mkclass_aligned() skips wrongly aligned potential candidates.
488 * [The only neutral demons are djinni and mail daemon and
489 * mkclass() won't pick them, but call it anyway in case either
490 * aspect of that changes someday.]
493 if (atyp == A_NEUTRAL)
496 ptr = mkclass_aligned(S_DEMON, 0, atyp);
497 return (ptr && is_ndemon(ptr)) ? monsndx(ptr) : NON_PM;
500 /* guardian angel has been affected by conflict so is abandoning hero */
502 lose_guardian_angel(mon)
503 struct monst *mon; /* if null, angel hasn't been created yet */
509 if (canspotmon(mon)) {
512 pline("%s rebukes you, saying:", Monnam(mon));
514 pline("%s
\82Í
\82 \82È
\82½
\82ð
\94ñ
\93ï
\82µ
\82½
\81F", Monnam(mon));
516 verbalize("Since you desire conflict, have some more!");
518 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");
521 pline("%s vanishes!", Monnam(mon));
523 pline("%s
\82Í
\8fÁ
\82¦
\82½
\81I", Monnam(mon));
528 /* create 2 to 4 hostile angels to replace the lost guardian */
529 for (i = rn1(3, 2); i > 0; --i) {
532 if (enexto(&mm, mm.x, mm.y, &mons[PM_ANGEL]))
533 (void) mk_roamer(&mons[PM_ANGEL], u.ualign.type, mm.x, mm.y,
538 /* just entered the Astral Plane; receive tame guardian angel if worthy */
540 gain_guardian_angel()
546 Hear_again(); /* attempt to cure any deafness now (divine
547 message will be heard even if that fails) */
551 pline("A voice booms:");
553 pline("
\90º
\82ª
\8b¿
\82¢
\82½:");
556 You_feel("a booming voice:");
558 You_feel("
\8b¿
\82
\90º
\82ð
\8a´
\82¶
\82½:");
560 verbalize("Thy desire for conflict shall be fulfilled!");
562 verbalize("
\81u
\93ð
\82Ì
\93¬
\91\88\82Ö
\82Ì
\96]
\82Ý
\81C
\82©
\82È
\82¦
\82ç
\82ê
\82é
\82×
\82µ
\81I
\81v");
563 /* send in some hostile angels instead */
564 lose_guardian_angel((struct monst *) 0);
565 } else if (u.ualign.record > 8) { /* fervent */
568 pline("A voice whispers:");
570 pline("
\82³
\82³
\82â
\82«
\90º
\82ª
\95·
\82±
\82¦
\82½:");
573 You_feel("a soft voice:");
575 You_feel("
\82â
\82í
\82ç
\82©
\82¢
\90º
\82ð
\8a´
\82¶
\82½:");
577 verbalize("Thou hast been worthy of me!");
579 verbalize("
\81u
\93ð
\81C
\89ä
\82ª
\95]
\89¿
\82ð
\93¾
\82½
\82è
\81I
\81v");
582 if (enexto(&mm, mm.x, mm.y, &mons[PM_ANGEL])
583 && (mtmp = mk_roamer(&mons[PM_ANGEL], u.ualign.type, mm.x, mm.y,
585 mtmp->mstrategy &= ~STRAT_APPEARMSG;
586 /* guardian angel -- the one case mtame doesn't imply an
587 * edog structure, so we don't want to call tamedog().
588 * [Note: this predates mon->mextra which allows a monster
589 * to have both emin and edog at the same time.]
592 /* for 'hilite_pet'; after making tame, before next message */
593 newsym(mtmp->mx, mtmp->my);
596 pline("An angel appears near you.");
598 pline("
\93V
\8eg
\82ª
\82 \82È
\82½
\82Ì
\82»
\82Î
\82É
\8c»
\82í
\82ê
\82½
\81D");
601 You_feel("the presence of a friendly angel near you.");
603 You("
\8bß
\82
\82É
\97F
\8dD
\93I
\82È
\93V
\8eg
\82Ì
\91¶
\8dÝ
\82ð
\8a´
\82¶
\82½
\81D");
604 /* make him strong enough vs. endgame foes */
605 mtmp->m_lev = rn1(8, 15);
606 mtmp->mhp = mtmp->mhpmax =
607 d((int) mtmp->m_lev, 10) + 30 + rnd(30);
608 if ((otmp = select_hwep(mtmp)) == 0) {
609 otmp = mksobj(SILVER_SABER, FALSE, FALSE);
610 if (mpickobj(mtmp, otmp))
611 panic("merged weapon?");
616 if ((otmp = which_armor(mtmp, W_ARMS)) == 0
617 || otmp->otyp != SHIELD_OF_REFLECTION) {
618 (void) mongets(mtmp, AMULET_OF_REFLECTION);
619 m_dowear(mtmp, TRUE);