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
);