1 /* SCCS Id: @(#)wizard.c 3.4 2003/02/18 */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
5 /* wizard code - inspired by rogue code from Merlyn Leroy (digi-g!brian) */
6 /* - heavily modified to give the wiz balls. (genat!mike) */
7 /* - dewimped and given some maledictions. -3. */
8 /* - generalized for 3.1 (mike@bullns.on01.bull.ca) */
14 extern const int monstr[];
18 STATIC_DCL short FDECL(which_arti, (int));
19 STATIC_DCL boolean FDECL(mon_has_arti, (struct monst *,SHORT_P));
20 STATIC_DCL struct monst *FDECL(other_mon_has_arti, (struct monst *,SHORT_P));
21 STATIC_DCL struct obj *FDECL(on_ground, (SHORT_P));
22 STATIC_DCL boolean FDECL(you_have, (int));
23 STATIC_DCL long FDECL(target_on, (int,struct monst *));
24 STATIC_DCL long FDECL(strategy, (struct monst *));
26 static NEARDATA const int nasties[] = {
27 PM_COCKATRICE, PM_ETTIN, PM_STALKER, PM_MINOTAUR, PM_RED_DRAGON,
28 PM_BLACK_DRAGON, PM_GREEN_DRAGON, PM_OWLBEAR, PM_PURPLE_WORM,
29 PM_ROCK_TROLL, PM_XAN, PM_GREMLIN, PM_UMBER_HULK, PM_VAMPIRE_LORD,
30 PM_XORN, PM_ZRUTY, PM_ELF_LORD, PM_ELVENKING, PM_YELLOW_DRAGON,
31 PM_LEOCROTTA, PM_BALUCHITHERIUM, PM_CARNIVOROUS_APE, PM_FIRE_GIANT,
32 PM_COUATL, PM_CAPTAIN, PM_WINGED_GARGOYLE, PM_MASTER_MIND_FLAYER,
33 PM_FIRE_ELEMENTAL, PM_JABBERWOCK, PM_ARCH_LICH, PM_OGRE_KING,
34 PM_OLOG_HAI, PM_IRON_GOLEM, PM_OCHRE_JELLY, PM_GREEN_SLIME,
38 static NEARDATA const unsigned wizapp[] = {
39 PM_HUMAN, PM_WATER_DEMON, PM_VAMPIRE,
40 PM_RED_DRAGON, PM_TROLL, PM_UMBER_HULK,
41 PM_XORN, PM_XAN, PM_COCKATRICE,
50 /* If you've found the Amulet, make the Wizard appear after some time */
51 /* Also, give hints about portal locations, if amulet is worn/wielded -dlc */
59 #if 0 /* caller takes care of this check */
63 if ((((amu = uamul) != 0 && amu->otyp == AMULET_OF_YENDOR) ||
64 ((amu = uwep) != 0 && amu->otyp == AMULET_OF_YENDOR))
66 for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) {
67 if(ttmp->ttyp == MAGIC_PORTAL) {
68 int du = distu(ttmp->tx, ttmp->ty);
70 pline("%s hot!", Tobjnam(amu, "feel"));
72 pline("%s very warm.", Tobjnam(amu, "feel"));
74 pline("%s warm.", Tobjnam(amu, "feel"));
75 /* else, the amulet feels normal */
81 if (!flags.no_of_wizards)
83 /* find Wizard, and wake him if necessary */
84 for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
85 if (!DEADMONSTER(mtmp) && mtmp->iswiz && mtmp->msleeping && !rn2(40)) {
87 if (distu(mtmp->mx,mtmp->my) > 2)
89 "get the creepy feeling that somebody noticed your taking the Amulet."
100 register struct monst *mtmp;
102 register struct obj *otmp;
104 for(otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
105 if(otmp->otyp == AMULET_OF_YENDOR) return(1);
110 mon_has_special(mtmp)
111 register struct monst *mtmp;
113 register struct obj *otmp;
115 for(otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
116 if(otmp->otyp == AMULET_OF_YENDOR ||
117 is_quest_artifact(otmp) ||
118 otmp->otyp == BELL_OF_OPENING ||
119 otmp->otyp == CANDELABRUM_OF_INVOCATION ||
120 otmp->otyp == SPE_BOOK_OF_THE_DEAD) return(1);
125 * New for 3.1 Strategy / Tactics for the wiz, as well as other
126 * monsters that are "after" something (defined via mflag3).
128 * The strategy section decides *what* the monster is going
129 * to attempt, the tactics section implements the decision.
131 #define STRAT(w, x, y, typ) (w | ((long)(x)<<16) | ((long)(y)<<8) | (long)typ)
133 #define M_Wants(mask) (mtmp->data->mflags3 & (mask))
140 case M3_WANTSAMUL: return(AMULET_OF_YENDOR);
141 case M3_WANTSBELL: return(BELL_OF_OPENING);
142 case M3_WANTSCAND: return(CANDELABRUM_OF_INVOCATION);
143 case M3_WANTSBOOK: return(SPE_BOOK_OF_THE_DEAD);
144 default: break; /* 0 signifies quest artifact */
150 * If "otyp" is zero, it triggers a check for the quest_artifact,
151 * since bell, book, candle, and amulet are all objects, not really
152 * artifacts right now. [MRS]
155 mon_has_arti(mtmp, otyp)
156 register struct monst *mtmp;
159 register struct obj *otmp;
161 for(otmp = mtmp->minvent; otmp; otmp = otmp->nobj) {
163 if(otmp->otyp == otyp)
166 else if(is_quest_artifact(otmp)) return(1);
172 STATIC_OVL struct monst *
173 other_mon_has_arti(mtmp, otyp)
174 register struct monst *mtmp;
177 register struct monst *mtmp2;
179 for(mtmp2 = fmon; mtmp2; mtmp2 = mtmp2->nmon)
180 /* no need for !DEADMONSTER check here since they have no inventory */
182 if(mon_has_arti(mtmp2, otyp)) return(mtmp2);
184 return((struct monst *)0);
187 STATIC_OVL struct obj *
191 register struct obj *otmp;
193 for (otmp = fobj; otmp; otmp = otmp->nobj)
195 if (otmp->otyp == otyp)
197 } else if (is_quest_artifact(otmp))
199 return((struct obj *)0);
207 case M3_WANTSAMUL: return(boolean)(u.uhave.amulet);
208 case M3_WANTSBELL: return(boolean)(u.uhave.bell);
209 case M3_WANTSCAND: return(boolean)(u.uhave.menorah);
210 case M3_WANTSBOOK: return(boolean)(u.uhave.book);
211 case M3_WANTSARTI: return(boolean)(u.uhave.questart);
218 target_on(mask, mtmp)
220 register struct monst *mtmp;
223 register struct obj *otmp;
224 register struct monst *mtmp2;
226 if(!M_Wants(mask)) return(STRAT_NONE);
228 otyp = which_arti(mask);
229 if(!mon_has_arti(mtmp, otyp)) {
231 return(STRAT(STRAT_PLAYER, u.ux, u.uy, mask));
232 else if((otmp = on_ground(otyp)))
233 return(STRAT(STRAT_GROUND, otmp->ox, otmp->oy, mask));
234 else if((mtmp2 = other_mon_has_arti(mtmp, otyp)))
235 return(STRAT(STRAT_MONSTR, mtmp2->mx, mtmp2->my, mask));
242 register struct monst *mtmp;
246 if (!is_covetous(mtmp->data) ||
247 /* perhaps a shopkeeper has been polymorphed into a master
248 lich; we don't want it teleporting to the stairs to heal
249 because that will leave its shop untended */
250 (mtmp->isshk && inhishop(mtmp)))
253 switch((mtmp->mhp*3)/mtmp->mhpmax) { /* 0-3 */
256 case 0: /* panic time - mtmp is almost snuffed */
259 case 1: /* the wiz is less cautious */
260 if(mtmp->data != &mons[PM_WIZARD_OF_YENDOR])
262 /* else fall through */
264 case 2: dstrat = STRAT_HEAL;
267 case 3: dstrat = STRAT_NONE;
271 if(flags.made_amulet)
272 if((strat = target_on(M3_WANTSAMUL, mtmp)) != STRAT_NONE)
275 if(u.uevent.invoked) { /* priorities change once gate opened */
277 if((strat = target_on(M3_WANTSARTI, mtmp)) != STRAT_NONE)
279 if((strat = target_on(M3_WANTSBOOK, mtmp)) != STRAT_NONE)
281 if((strat = target_on(M3_WANTSBELL, mtmp)) != STRAT_NONE)
283 if((strat = target_on(M3_WANTSCAND, mtmp)) != STRAT_NONE)
287 if((strat = target_on(M3_WANTSBOOK, mtmp)) != STRAT_NONE)
289 if((strat = target_on(M3_WANTSBELL, mtmp)) != STRAT_NONE)
291 if((strat = target_on(M3_WANTSCAND, mtmp)) != STRAT_NONE)
293 if((strat = target_on(M3_WANTSARTI, mtmp)) != STRAT_NONE)
301 register struct monst *mtmp;
303 long strat = strategy(mtmp);
305 mtmp->mstrategy = (mtmp->mstrategy & STRAT_WAITMASK) | strat;
308 case STRAT_HEAL: /* hide and recover */
309 /* if wounded, hole up on or near the stairs (to block them) */
310 /* unless, of course, there are no stairs (e.g. endlevel) */
311 mtmp->mavenge = 1; /* covetous monsters attack while fleeing */
312 if (In_W_tower(mtmp->mx, mtmp->my, &u.uz) ||
313 (mtmp->iswiz && !xupstair && !mon_has_amulet(mtmp))) {
314 if (!rn2(3 + mtmp->mhp/10)) (void) rloc(mtmp, FALSE);
315 } else if (xupstair &&
316 (mtmp->mx != xupstair || mtmp->my != yupstair)) {
317 (void) mnearto(mtmp, xupstair, yupstair, TRUE);
319 /* if you're not around, cast healing spells */
320 if (distu(mtmp->mx,mtmp->my) > (BOLT_LIM * BOLT_LIM))
321 if(mtmp->mhp <= mtmp->mhpmax - 8) {
325 /* fall through :-) */
327 case STRAT_NONE: /* harrass */
328 if (!rn2(!mtmp->mflee ? 5 : 33)) mnexto(mtmp);
331 default: /* kill, maim, pillage! */
333 long where = (strat & STRAT_STRATMASK);
334 xchar tx = STRAT_GOALX(strat),
335 ty = STRAT_GOALY(strat);
336 int targ = strat & STRAT_GOAL;
339 if(!targ) { /* simply wants you to close */
342 if((u.ux == tx && u.uy == ty) || where == STRAT_PLAYER) {
343 /* player is standing on it (or has it) */
347 if(where == STRAT_GROUND) {
348 if(!MON_AT(tx, ty) || (mtmp->mx == tx && mtmp->my == ty)) {
349 /* teleport to it and pick it up */
350 rloc_to(mtmp, tx, ty); /* clean old pos */
352 if ((otmp = on_ground(which_arti(targ))) != 0) {
353 if (cansee(mtmp->mx, mtmp->my))
354 pline("%s picks up %s.",
356 (distu(mtmp->mx, mtmp->my) <= 5) ?
357 doname(otmp) : distant_name(otmp, doname));
358 obj_extract_self(otmp);
359 (void) mpickobj(mtmp, otmp);
363 /* a monster is standing on it - cause some trouble */
364 if (!rn2(5)) mnexto(mtmp);
367 } else { /* a monster has it - 'port beside it. */
368 (void) mnearto(mtmp, tx, ty, FALSE);
380 register struct monst *mtmp;
382 for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
383 if (!DEADMONSTER(mtmp)) {
385 if(!mtmp->mcanmove && !rn2(5)) {
395 register struct monst *mtmp2;
397 if ((mtmp2 = makemon(&mons[PM_WIZARD_OF_YENDOR],
398 u.ux, u.uy, NO_MM_FLAGS)) != 0) {
399 mtmp2->msleeping = mtmp2->mtame = mtmp2->mpeaceful = 0;
400 if (!u.uhave.amulet && rn2(2)) { /* give clone a fake */
401 (void) add_to_minv(mtmp2, mksobj(FAKE_AMULET_OF_YENDOR,
404 mtmp2->m_ap_type = M_AP_MONSTER;
405 mtmp2->mappearance = wizapp[rn2(SIZE(wizapp))];
406 newsym(mtmp2->mx,mtmp2->my);
410 /* also used by newcham() */
414 /* To do? Possibly should filter for appropriate forms when
415 in the elemental planes or surrounded by water or lava. */
416 return nasties[rn2(SIZE(nasties))];
419 /* create some nasty monsters, aligned or neutral with the caster */
420 /* a null caster defaults to a chaotic caster (e.g. the wizard) */
425 register struct monst *mtmp;
426 register int i, j, tmp;
427 int castalign = (mcast ? mcast->data->maligntyp : -1);
431 if(!rn2(10) && Inhell) {
432 msummon((struct monst *) 0); /* summons like WoY */
435 tmp = (u.ulevel > 3) ? u.ulevel/3 : 1; /* just in case -- rph */
436 /* if we don't have a casting monster, the nasties appear around you */
439 for(i = rnd(tmp); i > 0; --i)
440 for(j=0; j<20; j++) {
443 /* Don't create more spellcasters of the monsters' level or
444 * higher--avoids chain summoners filling up the level.
447 makeindex = pick_nasty();
448 } while(mcast && attacktype(&mons[makeindex], AT_MAGC) &&
449 monstr[makeindex] >= monstr[mcast->mnum]);
450 /* do this after picking the monster to place */
452 !enexto(&bypos, mcast->mux, mcast->muy, &mons[makeindex]))
454 if ((mtmp = makemon(&mons[makeindex],
455 bypos.x, bypos.y, NO_MM_FLAGS)) != 0) {
456 mtmp->msleeping = mtmp->mpeaceful = mtmp->mtame = 0;
459 mtmp = makemon((struct permonst *)0,
460 bypos.x, bypos.y, NO_MM_FLAGS);
461 if(mtmp && (mtmp->data->maligntyp == 0 ||
462 sgn(mtmp->data->maligntyp) == sgn(castalign)) ) {
471 /* Let's resurrect the wizard, for some unexpected fun. */
475 struct monst *mtmp, **mmtmp;
479 if (!flags.no_of_wizards) {
480 /* make a new Wizard */
482 mtmp = makemon(&mons[PM_WIZARD_OF_YENDOR], u.ux, u.uy, MM_NOWAIT);
484 /* look for a migrating Wizard */
486 mmtmp = &migrating_mons;
487 while ((mtmp = *mmtmp) != 0) {
489 /* if he has the Amulet, he won't bring it to you */
490 !mon_has_amulet(mtmp) &&
491 (elapsed = monstermoves - mtmp->mlstmv) > 0L) {
492 mon_catchup_elapsed_time(mtmp, elapsed);
493 if (elapsed >= LARGEST_INT) elapsed = LARGEST_INT - 1;
495 if (mtmp->msleeping && rn2((int)elapsed + 1))
497 if (mtmp->mfrozen == 1) /* would unfreeze on next move */
498 mtmp->mfrozen = 0, mtmp->mcanmove = 1;
499 if (mtmp->mcanmove && !mtmp->msleeping) {
501 mon_arrive(mtmp, TRUE);
502 /* note: there might be a second Wizard; if so,
503 he'll have to wait til the next resurrection */
512 mtmp->msleeping = mtmp->mtame = mtmp->mpeaceful = 0;
514 pline("A voice booms out...");
515 verbalize("So thou thought thou couldst %s me, fool.", verb);
520 /* Here, we make trouble for the poor shmuck who actually */
521 /* managed to do in the Wizard. */
525 int which = Is_astralevel(&u.uz) ? rnd(4) : rn2(6);
526 /* cases 0 and 5 don't apply on the Astral level */
529 case 1: You_feel("vaguely nervous.");
532 You("notice a %s glow surrounding you.",
538 case 4: (void)nasty((struct monst *)0);
548 flags.no_of_wizards--;
549 if (!u.uevent.udemigod) {
550 u.uevent.udemigod = TRUE;
551 u.udg_cnt = rn1(250, 50);
555 const char * const random_insult[] = {
580 "villein", /* (sic.) */
586 const char * const random_malediction[] = {
587 "Hell shall soon claim thy remains,",
588 "I chortle at thee, thou pathetic",
589 "Prepare to die, thou",
590 "Resistance is useless,",
591 "Surrender or die, thou",
592 "There shall be no mercy, thou",
593 "Thou shalt repent of thy cunning,",
594 "Thou art as a flea to me,",
596 "Thy fate is sealed,",
597 "Verily, thou shalt be one dead"
600 /* Insult or intimidate the player */
603 register struct monst *mtmp;
606 if (!rn2(5)) /* typical bad guy action */
607 pline("%s laughs fiendishly.", Monnam(mtmp));
609 if (u.uhave.amulet && !rn2(SIZE(random_insult)))
610 verbalize("Relinquish the amulet, %s!",
611 random_insult[rn2(SIZE(random_insult))]);
612 else if (u.uhp < 5 && !rn2(2)) /* Panic */
614 "Even now thy life force ebbs, %s!" :
615 "Savor thy breath, %s, it be thy last!",
616 random_insult[rn2(SIZE(random_insult))]);
617 else if (mtmp->mhp < 5 && !rn2(2)) /* Parthian shot */
623 random_malediction[rn2(SIZE(random_malediction))],
624 random_insult[rn2(SIZE(random_insult))]);
625 } else if(is_lminion(mtmp)) {
626 com_pager(rn2(QTN_ANGELIC - 1 + (Hallucination ? 1 : 0)) +
630 pline("%s casts aspersions on your ancestry.", Monnam(mtmp));
632 com_pager(rn2(QTN_DEMONIC) + QT_DEMONIC);