1 /* NetHack 3.6 minion.c $NHDT-Date: 1432512773 2015/05/25 00:12:53 $ $NHDT-Branch: master $:$NHDT-Revision: 1.33 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
12 mtmp->mextra = newmextra();
14 EMIN(mtmp) = (struct emin *) alloc(sizeof(struct emin));
15 (void) memset((genericptr_t) EMIN(mtmp), 0, sizeof(struct emin));
23 if (mtmp->mextra && EMIN(mtmp)) {
24 free((genericptr_t) EMIN(mtmp));
25 EMIN(mtmp) = (struct emin *) 0;
30 /* count the number of monsters on the level */
32 monster_census(spotted)
33 boolean spotted; /* seen|sensed vs all */
38 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
39 if (DEADMONSTER(mtmp))
41 if (spotted && !canspotmon(mtmp))
48 /* mon summons a monster */
54 int dtype = NON_PM, cnt = 0, result = 0, census;
60 atyp = mon->ispriest ? EPRI(mon)->shralign
61 : mon->isminion ? EMIN(mon)->min_align
62 : (ptr->maligntyp == A_NONE)
64 : sgn(ptr->maligntyp);
66 ptr = &mons[PM_WIZARD_OF_YENDOR];
67 atyp = (ptr->maligntyp == A_NONE) ? A_NONE : sgn(ptr->maligntyp);
70 if (is_dprince(ptr) || (ptr == &mons[PM_WIZARD_OF_YENDOR])) {
71 dtype = (!rn2(20)) ? dprince(atyp) : (!rn2(4)) ? dlord(atyp)
73 cnt = (!rn2(4) && is_ndemon(&mons[dtype])) ? 2 : 1;
74 } else if (is_dlord(ptr)) {
75 dtype = (!rn2(50)) ? dprince(atyp) : (!rn2(20)) ? dlord(atyp)
77 cnt = (!rn2(4) && is_ndemon(&mons[dtype])) ? 2 : 1;
78 } else if (is_ndemon(ptr)) {
79 dtype = (!rn2(20)) ? dlord(atyp) : (!rn2(6)) ? ndemon(atyp)
82 } else if (is_lminion(mon)) {
83 dtype = (is_lord(ptr) && !rn2(20))
85 : (is_lord(ptr) || !rn2(6)) ? lminion() : monsndx(ptr);
86 cnt = (!rn2(4) && !is_lord(&mons[dtype])) ? 2 : 1;
87 } else if (ptr == &mons[PM_ANGEL]) {
88 /* non-lawful angels can also summon */
90 switch (atyp) { /* see summon_minion */
92 dtype = PM_AIR_ELEMENTAL + rn2(4);
102 cnt = (!rn2(4) && !is_lord(&mons[dtype])) ? 2 : 1;
109 if (cnt > 1 && (mons[dtype].geno & G_UNIQ))
112 * If this daemon is unique and being re-summoned (the only way we
113 * could get this far with an extinct dtype), try another.
115 if (mvitals[dtype].mvflags & G_GONE) {
116 dtype = ndemon(atyp);
121 /* some candidates can generate a group of monsters, so simple
122 count of non-null makemon() result is not sufficient */
123 census = monster_census(FALSE);
126 mtmp = makemon(&mons[dtype], u.ux, u.uy, MM_EMIN);
129 /* an angel's alignment should match the summoner */
130 if (dtype == PM_ANGEL) {
132 EMIN(mtmp)->min_align = atyp;
133 /* renegade if same alignment but not peaceful
134 or peaceful but different alignment */
135 EMIN(mtmp)->renegade =
136 (atyp != u.ualign.type) ^ !mtmp->mpeaceful;
142 /* how many monsters exist now compared to before? */
144 result = monster_census(FALSE) - census;
150 summon_minion(alignment, talk)
154 register struct monst *mon;
157 switch ((int) alignment) {
162 mnum = PM_AIR_ELEMENTAL + rn2(4);
166 mnum = ndemon(alignment);
169 impossible("unaligned player?");
170 mnum = ndemon(A_NONE);
173 if (mnum == NON_PM) {
175 } else if (mnum == PM_ANGEL) {
176 mon = makemon(&mons[mnum], u.ux, u.uy, MM_EMIN);
179 EMIN(mon)->min_align = alignment;
180 EMIN(mon)->renegade = FALSE;
182 } else if (mnum != PM_SHOPKEEPER && mnum != PM_GUARD
183 && mnum != PM_ALIGNED_PRIEST && mnum != PM_HIGH_PRIEST) {
184 /* This was mons[mnum].pxlth == 0 but is this restriction
185 appropriate or necessary now that the structures are separate? */
186 mon = makemon(&mons[mnum], u.ux, u.uy, MM_EMIN);
189 EMIN(mon)->min_align = alignment;
190 EMIN(mon)->renegade = FALSE;
193 mon = makemon(&mons[mnum], u.ux, u.uy, NO_MM_FLAGS);
197 pline_The("voice of %s booms:", align_gname(alignment));
198 verbalize("Thou shalt pay for thine indiscretion!");
200 pline("%s appears before you.", Amonnam(mon));
201 mon->mstrategy &= ~STRAT_APPEARMSG;
203 mon->mpeaceful = FALSE;
204 /* don't call set_malign(); player was naughty */
208 #define Athome (Inhell && (mtmp->cham == NON_PM))
210 /* returns 1 if it won't attack. */
213 register struct monst *mtmp;
215 long cash, demand, offer;
217 if (uwep && uwep->oartifact == ART_EXCALIBUR) {
218 pline("%s looks very angry.", Amonnam(mtmp));
219 mtmp->mpeaceful = mtmp->mtame = 0;
221 newsym(mtmp->mx, mtmp->my);
226 reset_faint(); /* if fainted - wake up */
235 /* Slight advantage given. */
236 if (is_dprince(mtmp->data) && mtmp->minvis) {
237 boolean wasunseen = !canspotmon(mtmp);
239 mtmp->minvis = mtmp->perminvis = 0;
240 if (wasunseen && canspotmon(mtmp)) {
241 pline("%s appears before you.", Amonnam(mtmp));
242 mtmp->mstrategy &= ~STRAT_APPEARMSG;
244 newsym(mtmp->mx, mtmp->my);
246 if (youmonst.data->mlet == S_DEMON) { /* Won't blackmail their own. */
247 pline("%s says, \"Good hunting, %s.\"", Amonnam(mtmp),
248 flags.female ? "Sister" : "Brother");
249 if (!tele_restrict(mtmp))
250 (void) rloc(mtmp, TRUE);
253 cash = money_cnt(invent);
255 (cash * (rnd(80) + 20 * Athome))
256 / (100 * (1 + (sgn(u.ualign.type) == sgn(mtmp->data->maligntyp))));
258 if (!demand || multi < 0) { /* you have no gold or can't move */
263 /* make sure that the demand is unmeetable if the monster
264 has the Amulet, preventing monster from being satisfied
265 and removed from the game (along with said Amulet...) */
266 if (mon_has_amulet(mtmp))
267 demand = cash + (long) rn1(1000, 40);
269 pline("%s demands %ld %s for safe passage.", Amonnam(mtmp), demand,
272 if ((offer = bribe(mtmp)) >= demand) {
273 pline("%s vanishes, laughing about cowardly mortals.",
275 } else if (offer > 0L && (long) rnd(40) > (demand - offer)) {
276 pline("%s scowls at you menacingly, then vanishes.",
279 pline("%s gets angry...", Amonnam(mtmp));
295 long umoney = money_cnt(invent);
297 getlin("How much will you offer?", buf);
298 if (sscanf(buf, "%ld", &offer) != 1)
301 /*Michael Paddon -- fix for negative offer to monster*/
304 You("try to shortchange %s, but fumble.", mon_nam(mtmp));
306 } else if (offer == 0L) {
309 } else if (offer >= umoney) {
310 You("give %s all your gold.", mon_nam(mtmp));
313 You("give %s %ld %s.", mon_nam(mtmp), offer, currency(offer));
315 (void) money2mon(mtmp, offer);
326 for (tryct = !In_endgame(&u.uz) ? 20 : 0; tryct > 0; --tryct) {
327 pm = rn1(PM_DEMOGORGON + 1 - PM_ORCUS, PM_ORCUS);
328 if (!(mvitals[pm].mvflags & G_GONE)
329 && (atyp == A_NONE || sgn(mons[pm].maligntyp) == sgn(atyp)))
332 return (dlord(atyp)); /* approximate */
341 for (tryct = !In_endgame(&u.uz) ? 20 : 0; tryct > 0; --tryct) {
342 pm = rn1(PM_YEENOGHU + 1 - PM_JUIBLEX, PM_JUIBLEX);
343 if (!(mvitals[pm].mvflags & G_GONE)
344 && (atyp == A_NONE || sgn(mons[pm].maligntyp) == sgn(atyp)))
347 return (ndemon(atyp)); /* approximate */
350 /* create lawful (good) lord */
354 if (!(mvitals[PM_ARCHON].mvflags & G_GONE))
357 return (lminion()); /* approximate */
364 struct permonst *ptr;
366 for (tryct = 0; tryct < 20; tryct++) {
367 ptr = mkclass(S_ANGEL, 0);
368 if (ptr && !is_lord(ptr))
369 return (monsndx(ptr));
380 struct permonst *ptr;
382 for (tryct = 0; tryct < 20; tryct++) {
383 ptr = mkclass(S_DEMON, 0);
384 if (ptr && is_ndemon(ptr)
385 && (atyp == A_NONE || sgn(ptr->maligntyp) == sgn(atyp)))
386 return (monsndx(ptr));
392 /* guardian angel has been affected by conflict so is abandoning hero */
394 lose_guardian_angel(mon)
395 struct monst *mon; /* if null, angel hasn't been created yet */
401 if (canspotmon(mon)) {
403 pline("%s rebukes you, saying:", Monnam(mon));
404 verbalize("Since you desire conflict, have some more!");
406 pline("%s vanishes!", Monnam(mon));
411 /* create 2 to 4 hostile angels to replace the lost guardian */
412 for (i = rn1(3, 2); i > 0; --i) {
415 if (enexto(&mm, mm.x, mm.y, &mons[PM_ANGEL]))
416 (void) mk_roamer(&mons[PM_ANGEL], u.ualign.type, mm.x, mm.y,
421 /* just entered the Astral Plane; receive tame guardian angel if worthy */
423 gain_guardian_angel()
429 Hear_again(); /* attempt to cure any deafness now (divine
430 message will be heard even if that fails) */
432 pline("A voice booms:");
433 verbalize("Thy desire for conflict shall be fulfilled!");
434 /* send in some hostile angels instead */
435 lose_guardian_angel((struct monst *) 0);
436 } else if (u.ualign.record > 8) { /* fervent */
437 pline("A voice whispers:");
438 verbalize("Thou hast been worthy of me!");
441 if (enexto(&mm, mm.x, mm.y, &mons[PM_ANGEL])
442 && (mtmp = mk_roamer(&mons[PM_ANGEL], u.ualign.type, mm.x, mm.y,
444 mtmp->mstrategy &= ~STRAT_APPEARMSG;
446 pline("An angel appears near you.");
448 You_feel("the presence of a friendly angel near you.");
449 /* guardian angel -- the one case mtame doesn't
450 * imply an edog structure, so we don't want to
454 /* make him strong enough vs. endgame foes */
455 mtmp->m_lev = rn1(8, 15);
456 mtmp->mhp = mtmp->mhpmax =
457 d((int) mtmp->m_lev, 10) + 30 + rnd(30);
458 if ((otmp = select_hwep(mtmp)) == 0) {
459 otmp = mksobj(SILVER_SABER, FALSE, FALSE);
460 if (mpickobj(mtmp, otmp))
461 panic("merged weapon?");
466 if ((otmp = which_armor(mtmp, W_ARMS)) == 0
467 || otmp->otyp != SHIELD_OF_REFLECTION) {
468 (void) mongets(mtmp, AMULET_OF_REFLECTION);
469 m_dowear(mtmp, TRUE);