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
;
61 if (uwep
&& uwep
->oartifact
== ART_DEMONBANE
&& is_demon(ptr
)) {
63 pline("%s looks puzzled for a moment.", Monnam(mon
));
67 atyp
= mon
->ispriest
? EPRI(mon
)->shralign
68 : mon
->isminion
? EMIN(mon
)->min_align
69 : (ptr
->maligntyp
== A_NONE
)
71 : sgn(ptr
->maligntyp
);
73 ptr
= &mons
[PM_WIZARD_OF_YENDOR
];
74 atyp
= (ptr
->maligntyp
== A_NONE
) ? A_NONE
: sgn(ptr
->maligntyp
);
77 if (is_dprince(ptr
) || (ptr
== &mons
[PM_WIZARD_OF_YENDOR
])) {
78 dtype
= (!rn2(20)) ? dprince(atyp
) : (!rn2(4)) ? dlord(atyp
)
80 cnt
= (!rn2(4) && is_ndemon(&mons
[dtype
])) ? 2 : 1;
81 } else if (is_dlord(ptr
)) {
82 dtype
= (!rn2(50)) ? dprince(atyp
) : (!rn2(20)) ? dlord(atyp
)
84 cnt
= (!rn2(4) && is_ndemon(&mons
[dtype
])) ? 2 : 1;
85 } else if (is_ndemon(ptr
)) {
86 dtype
= (!rn2(20)) ? dlord(atyp
) : (!rn2(6)) ? ndemon(atyp
)
89 } else if (is_lminion(mon
)) {
90 dtype
= (is_lord(ptr
) && !rn2(20))
92 : (is_lord(ptr
) || !rn2(6)) ? lminion() : monsndx(ptr
);
93 cnt
= (!rn2(4) && !is_lord(&mons
[dtype
])) ? 2 : 1;
94 } else if (ptr
== &mons
[PM_ANGEL
]) {
95 /* non-lawful angels can also summon */
97 switch (atyp
) { /* see summon_minion */
99 dtype
= PM_AIR_ELEMENTAL
+ rn2(4);
103 dtype
= ndemon(atyp
);
109 cnt
= (!rn2(4) && !is_lord(&mons
[dtype
])) ? 2 : 1;
116 if (cnt
> 1 && (mons
[dtype
].geno
& G_UNIQ
))
119 * If this daemon is unique and being re-summoned (the only way we
120 * could get this far with an extinct dtype), try another.
122 if (mvitals
[dtype
].mvflags
& G_GONE
) {
123 dtype
= ndemon(atyp
);
128 /* some candidates can generate a group of monsters, so simple
129 count of non-null makemon() result is not sufficient */
130 census
= monster_census(FALSE
);
133 mtmp
= makemon(&mons
[dtype
], u
.ux
, u
.uy
, MM_EMIN
);
136 /* an angel's alignment should match the summoner */
137 if (dtype
== PM_ANGEL
) {
139 EMIN(mtmp
)->min_align
= atyp
;
140 /* renegade if same alignment but not peaceful
141 or peaceful but different alignment */
142 EMIN(mtmp
)->renegade
=
143 (atyp
!= u
.ualign
.type
) ^ !mtmp
->mpeaceful
;
149 /* how many monsters exist now compared to before? */
151 result
= monster_census(FALSE
) - census
;
157 summon_minion(alignment
, talk
)
161 register struct monst
*mon
;
164 switch ((int) alignment
) {
169 mnum
= PM_AIR_ELEMENTAL
+ rn2(4);
173 mnum
= ndemon(alignment
);
176 impossible("unaligned player?");
177 mnum
= ndemon(A_NONE
);
180 if (mnum
== NON_PM
) {
182 } else if (mnum
== PM_ANGEL
) {
183 mon
= makemon(&mons
[mnum
], u
.ux
, u
.uy
, MM_EMIN
);
186 EMIN(mon
)->min_align
= alignment
;
187 EMIN(mon
)->renegade
= FALSE
;
189 } else if (mnum
!= PM_SHOPKEEPER
&& mnum
!= PM_GUARD
190 && mnum
!= PM_ALIGNED_PRIEST
&& mnum
!= PM_HIGH_PRIEST
) {
191 /* This was mons[mnum].pxlth == 0 but is this restriction
192 appropriate or necessary now that the structures are separate? */
193 mon
= makemon(&mons
[mnum
], u
.ux
, u
.uy
, MM_EMIN
);
196 EMIN(mon
)->min_align
= alignment
;
197 EMIN(mon
)->renegade
= FALSE
;
200 mon
= makemon(&mons
[mnum
], u
.ux
, u
.uy
, NO_MM_FLAGS
);
204 pline_The("voice of %s booms:", align_gname(alignment
));
205 verbalize("Thou shalt pay for thine indiscretion!");
207 pline("%s appears before you.", Amonnam(mon
));
208 mon
->mstrategy
&= ~STRAT_APPEARMSG
;
210 mon
->mpeaceful
= FALSE
;
211 /* don't call set_malign(); player was naughty */
215 #define Athome (Inhell && (mtmp->cham == NON_PM))
217 /* returns 1 if it won't attack. */
220 register struct monst
*mtmp
;
222 long cash
, demand
, offer
;
224 if (uwep
&& uwep
->oartifact
== ART_EXCALIBUR
) {
225 pline("%s looks very angry.", Amonnam(mtmp
));
226 mtmp
->mpeaceful
= mtmp
->mtame
= 0;
228 newsym(mtmp
->mx
, mtmp
->my
);
233 reset_faint(); /* if fainted - wake up */
242 /* Slight advantage given. */
243 if (is_dprince(mtmp
->data
) && mtmp
->minvis
) {
244 boolean wasunseen
= !canspotmon(mtmp
);
246 mtmp
->minvis
= mtmp
->perminvis
= 0;
247 if (wasunseen
&& canspotmon(mtmp
)) {
248 pline("%s appears before you.", Amonnam(mtmp
));
249 mtmp
->mstrategy
&= ~STRAT_APPEARMSG
;
251 newsym(mtmp
->mx
, mtmp
->my
);
253 if (youmonst
.data
->mlet
== S_DEMON
) { /* Won't blackmail their own. */
254 pline("%s says, \"Good hunting, %s.\"", Amonnam(mtmp
),
255 flags
.female
? "Sister" : "Brother");
256 if (!tele_restrict(mtmp
))
257 (void) rloc(mtmp
, TRUE
);
260 cash
= money_cnt(invent
);
262 (cash
* (rnd(80) + 20 * Athome
))
263 / (100 * (1 + (sgn(u
.ualign
.type
) == sgn(mtmp
->data
->maligntyp
))));
265 if (!demand
|| multi
< 0) { /* you have no gold or can't move */
270 /* make sure that the demand is unmeetable if the monster
271 has the Amulet, preventing monster from being satisfied
272 and removed from the game (along with said Amulet...) */
273 if (mon_has_amulet(mtmp
))
274 demand
= cash
+ (long) rn1(1000, 40);
276 pline("%s demands %ld %s for safe passage.", Amonnam(mtmp
), demand
,
279 if ((offer
= bribe(mtmp
)) >= demand
) {
280 pline("%s vanishes, laughing about cowardly mortals.",
282 } else if (offer
> 0L && (long) rnd(40) > (demand
- offer
)) {
283 pline("%s scowls at you menacingly, then vanishes.",
286 pline("%s gets angry...", Amonnam(mtmp
));
302 long umoney
= money_cnt(invent
);
304 getlin("How much will you offer?", buf
);
305 if (sscanf(buf
, "%ld", &offer
) != 1)
308 /*Michael Paddon -- fix for negative offer to monster*/
311 You("try to shortchange %s, but fumble.", mon_nam(mtmp
));
313 } else if (offer
== 0L) {
316 } else if (offer
>= umoney
) {
317 You("give %s all your gold.", mon_nam(mtmp
));
320 You("give %s %ld %s.", mon_nam(mtmp
), offer
, currency(offer
));
322 (void) money2mon(mtmp
, offer
);
333 for (tryct
= !In_endgame(&u
.uz
) ? 20 : 0; tryct
> 0; --tryct
) {
334 pm
= rn1(PM_DEMOGORGON
+ 1 - PM_ORCUS
, PM_ORCUS
);
335 if (!(mvitals
[pm
].mvflags
& G_GONE
)
336 && (atyp
== A_NONE
|| sgn(mons
[pm
].maligntyp
) == sgn(atyp
)))
339 return (dlord(atyp
)); /* approximate */
348 for (tryct
= !In_endgame(&u
.uz
) ? 20 : 0; tryct
> 0; --tryct
) {
349 pm
= rn1(PM_YEENOGHU
+ 1 - PM_JUIBLEX
, PM_JUIBLEX
);
350 if (!(mvitals
[pm
].mvflags
& G_GONE
)
351 && (atyp
== A_NONE
|| sgn(mons
[pm
].maligntyp
) == sgn(atyp
)))
354 return (ndemon(atyp
)); /* approximate */
357 /* create lawful (good) lord */
361 if (!(mvitals
[PM_ARCHON
].mvflags
& G_GONE
))
364 return (lminion()); /* approximate */
371 struct permonst
*ptr
;
373 for (tryct
= 0; tryct
< 20; tryct
++) {
374 ptr
= mkclass(S_ANGEL
, 0);
375 if (ptr
&& !is_lord(ptr
))
376 return (monsndx(ptr
));
387 struct permonst
*ptr
;
389 for (tryct
= 0; tryct
< 20; tryct
++) {
390 ptr
= mkclass(S_DEMON
, 0);
391 if (ptr
&& is_ndemon(ptr
)
392 && (atyp
== A_NONE
|| sgn(ptr
->maligntyp
) == sgn(atyp
)))
393 return (monsndx(ptr
));
399 /* guardian angel has been affected by conflict so is abandoning hero */
401 lose_guardian_angel(mon
)
402 struct monst
*mon
; /* if null, angel hasn't been created yet */
408 if (canspotmon(mon
)) {
410 pline("%s rebukes you, saying:", Monnam(mon
));
411 verbalize("Since you desire conflict, have some more!");
413 pline("%s vanishes!", Monnam(mon
));
418 /* create 2 to 4 hostile angels to replace the lost guardian */
419 for (i
= rn1(3, 2); i
> 0; --i
) {
422 if (enexto(&mm
, mm
.x
, mm
.y
, &mons
[PM_ANGEL
]))
423 (void) mk_roamer(&mons
[PM_ANGEL
], u
.ualign
.type
, mm
.x
, mm
.y
,
428 /* just entered the Astral Plane; receive tame guardian angel if worthy */
430 gain_guardian_angel()
436 Hear_again(); /* attempt to cure any deafness now (divine
437 message will be heard even if that fails) */
439 pline("A voice booms:");
440 verbalize("Thy desire for conflict shall be fulfilled!");
441 /* send in some hostile angels instead */
442 lose_guardian_angel((struct monst
*) 0);
443 } else if (u
.ualign
.record
> 8) { /* fervent */
444 pline("A voice whispers:");
445 verbalize("Thou hast been worthy of me!");
448 if (enexto(&mm
, mm
.x
, mm
.y
, &mons
[PM_ANGEL
])
449 && (mtmp
= mk_roamer(&mons
[PM_ANGEL
], u
.ualign
.type
, mm
.x
, mm
.y
,
451 mtmp
->mstrategy
&= ~STRAT_APPEARMSG
;
453 pline("An angel appears near you.");
455 You_feel("the presence of a friendly angel near you.");
456 /* guardian angel -- the one case mtame doesn't
457 * imply an edog structure, so we don't want to
461 /* make him strong enough vs. endgame foes */
462 mtmp
->m_lev
= rn1(8, 15);
463 mtmp
->mhp
= mtmp
->mhpmax
=
464 d((int) mtmp
->m_lev
, 10) + 30 + rnd(30);
465 if ((otmp
= select_hwep(mtmp
)) == 0) {
466 otmp
= mksobj(SILVER_SABER
, FALSE
, FALSE
);
467 if (mpickobj(mtmp
, otmp
))
468 panic("merged weapon?");
473 if ((otmp
= which_armor(mtmp
, W_ARMS
)) == 0
474 || otmp
->otyp
!= SHIELD_OF_REFLECTION
) {
475 (void) mongets(mtmp
, AMULET_OF_REFLECTION
);
476 m_dowear(mtmp
, TRUE
);